dev(SF-60): Доработан канал передачи данных ethernet

This commit is contained in:
algin 2023-10-24 14:02:04 +03:00
parent 9a84db4431
commit 6f3fe15497
20 changed files with 278 additions and 118 deletions

View File

@ -32,7 +32,7 @@ static void eth_initTxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue)
uint32_t i;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int i_max = (ENET_SYSCFG_TOTAL_NUM_TX_PKT/2);
int i_max = ENET_SYSCFG_TOTAL_NUM_TX_PKT;
/* Initialize TX EthPkts and queue them to txFreePktInfoQ */
for (i = 0U; i < i_max; i++)
@ -125,7 +125,7 @@ bool free_rtos::EthTxFlow::open(uint32_t id, int32_t enetDmaTxChId)
dma_handle_ = txChInfo.hTxCh;
EnetAppUtils_assert(txChInfo.useGlobalEvt == true);
EnetAppUtils_assert(txChInfo.maxNumTxPkts >= (ENET_SYSCFG_TOTAL_NUM_TX_PKT/2U));
EnetAppUtils_assert(txChInfo.maxNumTxPkts >= ENET_SYSCFG_TOTAL_NUM_TX_PKT);
if (dma_handle_ == nullptr)
{
@ -224,20 +224,19 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
return true;
}
bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, Handler *handler, uint32_t numScatterSegments)
bool free_rtos::EthTxFlow::send(TxFlowHandlerArgs& handlerArgs, uint32_t numScatterSegments)
{
if (port_id >= e_ethMacTotal) {
if (handlerArgs.port_id >= e_ethMacTotal) {
return false;
}
if (!port_data_[port_id].tx_enable) {
if (!port_data_[handlerArgs.port_id].tx_enable) {
return false;
}
EnetDma_PktQ txSubmitQ;
EnetDma_Pkt *txPktInfo;
int32_t status;
uint32_t len;
eth_retrieveFreeTxPkts(&dma_handle_, &tx_free_pktq_);
@ -248,9 +247,8 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, Handler *handler, uint32_t
{
for(size_t scatter_segment = 0; scatter_segment < numScatterSegments; scatter_segment++)
{
len = handler->Sender(txPktInfo->sgList.list[scatter_segment].bufPtr, scatter_segment);
txPktInfo->sgList.list[scatter_segment].segmentFilledLen = len;
handlerArgs.buffer = txPktInfo->sgList.list[scatter_segment].bufPtr;
txPktInfo->sgList.list[scatter_segment].segmentFilledLen = handlerArgs.stack_handler->Sender(handlerArgs, scatter_segment);
}
txPktInfo->sgList.numScatterSegments = numScatterSegments;
@ -259,7 +257,7 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, Handler *handler, uint32_t
txPktInfo->tsInfo.txPktSeqId = 0;
txPktInfo->txPktTc = 0; /// Traffic class <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> IPv6
txPktInfo->tsInfo.enableHostTxTs = false;
txPktInfo->txPortNum = (Enet_MacPort)port_id;
txPktInfo->txPortNum = (Enet_MacPort)handlerArgs.port_id;
EnetDma_checkPktState(&txPktInfo->pktState,
ENET_PKTSTATE_MODULE_APP,
@ -281,7 +279,7 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, Handler *handler, uint32_t
return false;
}
++port_data_[port_id].tx_pkt_counter; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
++port_data_[handlerArgs.port_id].tx_pkt_counter; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return true;
}

View File

@ -29,7 +29,7 @@ public:
void disable(TEthMacPorts port_id);
virtual bool send(TEthMacPorts port_id, uint8_t * p_data, uint32_t len) override;
virtual bool send(TEthMacPorts port_id, Handler * handler, uint32_t numScatterSegments) override;
virtual bool send(TxFlowHandlerArgs& handlerArgs, uint32_t numScatterSegments) override;
private:
struct PortData {
bool tx_enable;

View File

@ -12,10 +12,15 @@
#include "free_rtos/ethernet/eth_types.h"
#include "free_rtos/handler_store/handler_store.hpp"
struct TxFlowHandlerArgs : public HandlerArgs {
TEthMacPorts port_id;
Handler * stack_handler;
};
class EthTxFlowIface {
public:
virtual bool send(TEthMacPorts port_id, uint8_t * p_data, uint32_t len) = 0;
virtual bool send(TEthMacPorts port_id, Handler * handler, uint32_t numScatterSegments) = 0;
virtual bool send(TxFlowHandlerArgs& handlerArgs, uint32_t numScatterSegments) = 0;
virtual ~EthTxFlowIface(){}
};

View File

@ -51,12 +51,12 @@ int32_t EcatTelegram::Process(uint8_t *p_data, uint32_t len) {
return 0;
}
uint32_t EcatTelegram::Sender(uint8_t *p_data, size_t scatter_segment) {
uint8_t *raw = pack(p_data);
uint32_t EcatTelegram::Sender(HandlerArgs& handlerArgs, size_t scatter_segment) {
uint8_t *raw = pack(handlerArgs.buffer);
//DebugP_log((char*)"Sender started\r\n");
return raw - p_data;
return raw - handlerArgs.buffer;
}
uint8_t* EcatTelegram::pack(uint8_t *raw) {
@ -99,6 +99,7 @@ bool EcatTelegram::transfer() {
MAKE_AUTO_PROFILER(transfer, 32);
auto first = datagram_queue_.get_first();
TxFlowHandlerArgs txFlowHandlerArgs;
uint32_t transfer_attempts = 0;
uint32_t tick_counter_start;
uint32_t tick_counter_diff;
@ -115,6 +116,9 @@ bool EcatTelegram::transfer() {
first->reset_all_wkc();
txFlowHandlerArgs.port_id = port_id_;
txFlowHandlerArgs.stack_handler = this;
while(1) {
tick_counter_start = ecat_timer_.Wait();
@ -135,8 +139,7 @@ bool EcatTelegram::transfer() {
break;
}
// status = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1);
status = tx_flow_.send(port_id_, this, 1);
status = tx_flow_.send(txFlowHandlerArgs, 1);
if(status == false) {
status_.transfer_errors++;

View File

@ -66,7 +66,7 @@ public:
}
virtual int32_t Process(uint8_t *p_data, uint32_t len) override;
virtual uint32_t Sender(uint8_t *p_data, size_t scatter_segment) override;
virtual uint32_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) override;
void init(TEthMacPorts port_id, uint32_t period_microsec, uint32_t max_transfer_attempts) {
port_id_ = port_id;

View File

@ -205,7 +205,7 @@ int32_t free_rtos::EthArp::Process(uint8_t * p_data, uint32_t len)
return 0;
}
uint32_t free_rtos::EthArp::Sender(uint8_t * p_data, size_t scatter_segment)
uint32_t free_rtos::EthArp::Sender(HandlerArgs& handlerArgs, size_t scatter_segment)
{
return 0;
}

View File

@ -32,7 +32,7 @@ public:
bool try_request(uint32_t ip);
virtual int32_t Process(uint8_t * p_data, uint32_t len) override;
virtual uint32_t Sender(uint8_t * p_data, size_t scatter_segment) override;
virtual uint32_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) override;
private:
bool request(uint32_t ip);

View File

@ -40,7 +40,7 @@ int32_t free_rtos::EthIcmp::Process(uint8_t * p_data, uint32_t len)
return len;
}
uint32_t free_rtos::EthIcmp::Sender(uint8_t * p_data, size_t scatter_segment)
uint32_t free_rtos::EthIcmp::Sender(HandlerArgs& handlerArgs, size_t scatter_segment)
{
return 0;
}

View File

@ -18,7 +18,7 @@ namespace free_rtos {
class EthIcmp : public Handler {
public:
virtual int32_t Process(uint8_t * p_data, uint32_t len) override;
virtual uint32_t Sender(uint8_t * p_data, size_t scatter_segment) override;
virtual uint32_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) override;
uint32_t getStat() {return rx_cnt_;};
private:

View File

@ -37,44 +37,6 @@ free_rtos::EthIp::EthIp(EthStackIface& eth_stack, EthArpIface& arp) :
}
int32_t free_rtos::EthIp::Process(uint8_t * p_data, uint32_t len)
{
TIpHeader * ip_hdr = (TIpHeader *)p_data;
uint32_t ip_addr;
memcpy(&ip_addr, ip_hdr->ip_dst, ETH_IP_ADDR_LEN);
if (ip_addr != self_ip_) {
return 0;
}
int32_t reply = handlers_.Process(ip_hdr->ip_p, p_data + sizeof(TIpHeader), len - sizeof(TIpHeader));
if (reply > 0) {
uint16_t cksum;
uint16_t len;
/* Swap the IP destination address and the IP source address */
ip_swap_ip(ip_hdr->ip_dst, ip_hdr->ip_src);
reply += sizeof(TIpHeader);
ip_hdr->ip_len = BASE_SWAP16(reply);
ip_hdr->ip_id = BASE_SWAP16(ip_indet_);
//-------------------------------------------------------
ip_hdr->ip_sum = 0;
len = (ip_hdr->ip_hl_v & 0x0F) * 4;
cksum = eth_calcChksum(0,(uint8_t *)ip_hdr, len);
ip_hdr->ip_sum = BASE_SWAP16(cksum);
//-------------------------------------------------------
++ip_indet_;
}
return reply;
}
uint32_t free_rtos::EthIp::Sender(uint8_t * p_data, size_t scatter_segment)
{
return 0;
}
bool free_rtos::EthIp::send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot_id, TEthPkt& pkt)
{
uint64_t mac_dst;
@ -127,6 +89,105 @@ bool free_rtos::EthIp::send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot
return eth_stack_.send_pkt(port_id, mac_dst, ETH_PROT_IP_BE, pkt);
}
bool free_rtos::EthIp::send(IpHandlerArgs& handlerArgs)
{
handlerArgs.stack_handler = this;
return eth_stack_.send_pkt(handlerArgs);
}
inline uint32_t free_rtos::EthIp::fillEthFrameHeader(IpHandlerArgs& ipHandlerArgs)
{
TEthFrameHeader * p_eth_hdr = (TEthFrameHeader *)ipHandlerArgs.buffer;
uint64_t mac_dst;
if (!arp_.getMacAddr(ipHandlerArgs.dest_ip, mac_dst)) {
return 0;
}
p_eth_hdr->prot_id = ipHandlerArgs.ip_prot_id;
memcpy(p_eth_hdr->mac_src, &self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(p_eth_hdr->mac_dest, &mac_dst, ETH_FRAME_MAC_ADDR_LEN_BYTES);
return sizeof(TEthFrameHeader);
}
inline uint32_t free_rtos::EthIp::fillIpHeader(IpHandlerArgs& ipHandlerArgs, uint32_t ip_len)
{
TIpHeader * ip_header = (TIpHeader *)(ipHandlerArgs.buffer + sizeof(TEthFrameHeader));
uint16_t cksum = 0;
memcpy(ip_header->ip_src, &self_ip_, ETH_IP_ADDR_LEN);
memcpy(ip_header->ip_dst, &ipHandlerArgs.dest_ip, ETH_IP_ADDR_LEN);
ip_header->ip_hl_v = (IP_VER << 4) | IP_HEADER_WORD_SIZE;
ip_header->ip_tos = 0;
ip_header->ip_len = BASE_SWAP16(ip_len);
ip_header->ip_id = BASE_SWAP16(ip_indet_);
ip_header->ip_off = 0;
ip_header->ip_ttl = IP_TIME_TO_LIVE;
ip_header->ip_p = ipHandlerArgs.ip_prot_id;
ip_header->ip_sum = 0;
cksum = eth_calcChksum(0, (uint8_t *)ip_header, sizeof(TIpHeader));
ip_header->ip_sum = BASE_SWAP16(cksum);
++ip_indet_;
return sizeof(TIpHeader);
}
uint32_t free_rtos::EthIp::Sender(HandlerArgs& handlerArgs, size_t scatter_segment)
{
static_assert(sizeof(TIpHeader) == (IP_HEADER_WORD_SIZE * 4), "Ip header size doesn't match version !");
IpHandlerArgs& ipHandlerArgs = static_cast<IpHandlerArgs&>(handlerArgs); // downcasting back to derived type
uint32_t ip_len = ipHandlerArgs.ip_handler->Sender(ipHandlerArgs, scatter_segment);
if(fillEthFrameHeader(ipHandlerArgs) == 0) {
return 0;
}
fillIpHeader(ipHandlerArgs, ip_len);
return sizeof(TEthFrameHeader) + sizeof(TIpHeader) + ip_len;
}
int32_t free_rtos::EthIp::Process(uint8_t * p_data, uint32_t len)
{
TIpHeader * ip_hdr = (TIpHeader *)p_data;
uint32_t ip_addr;
memcpy(&ip_addr, ip_hdr->ip_dst, ETH_IP_ADDR_LEN);
if (ip_addr != self_ip_) {
return 0;
}
int32_t reply = handlers_.Process(ip_hdr->ip_p, p_data + sizeof(TIpHeader), len - sizeof(TIpHeader));
if (reply > 0) {
uint16_t cksum;
uint16_t len;
/* Swap the IP destination address and the IP source address */
ip_swap_ip(ip_hdr->ip_dst, ip_hdr->ip_src);
reply += sizeof(TIpHeader);
ip_hdr->ip_len = BASE_SWAP16(reply);
ip_hdr->ip_id = BASE_SWAP16(ip_indet_);
//-------------------------------------------------------
ip_hdr->ip_sum = 0;
len = (ip_hdr->ip_hl_v & 0x0F) * 4;
cksum = eth_calcChksum(0,(uint8_t *)ip_hdr, len);
ip_hdr->ip_sum = BASE_SWAP16(cksum);
//-------------------------------------------------------
++ip_indet_;
}
return reply;
}
bool free_rtos::EthIp::Register(uint8_t prot_id, Handler * p_handler)
{
return handlers_.Register(prot_id, p_handler);

View File

@ -8,6 +8,8 @@
#ifndef FREE_RTOS_ETHERNET_IP_ETH_IP_HPP_
#define FREE_RTOS_ETHERNET_IP_ETH_IP_HPP_
#include <networking/enet/utils/include/enet_apputils.h>
#include "free_rtos/handler_store/handler_store.hpp"
#include "free_rtos/ethernet_ip/eth_stack_iface.hpp"
#include "free_rtos/ethernet/eth_frame.h"
@ -23,14 +25,15 @@ public:
EthIp(EthStackIface& eth_stack, EthArpIface& arp);
void setSelfIpAddr(uint32_t ip) {self_ip_ = ip;};
void setSelfMac(uint64_t mac) {self_mac_ = mac;};
virtual uint32_t getSelfIpAddr() override {return self_ip_;};
virtual int32_t Process(uint8_t * p_data, uint32_t len) override;
virtual uint32_t Sender(uint8_t * p_data, size_t scatter_segment) override;
virtual bool send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot_id, TEthPkt& pkt) override;
virtual bool send(IpHandlerArgs& handlerArgs) override;
virtual int32_t Process(uint8_t * p_data, uint32_t len) override;
virtual uint32_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) override;
bool Register(uint8_t prot_id, Handler * p_handler);
@ -40,9 +43,13 @@ private:
EthStackIface& eth_stack_;
EthArpIface& arp_;
uint16_t ip_indet_; /// <20><><EFBFBD><EFBFBD> ip_id
uint32_t self_ip_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip-<2D><><EFBFBD><EFBFBD><EFBFBD>
uint64_t self_mac_;
uint16_t ip_indet_; /// \u043f\u0457\u0405\u043f\u0457\u0405\u043f\u0457\u0405\u043f\u0457\u0405 ip_id
inline uint32_t fillEthFrameHeader(IpHandlerArgs& ipHandlerArgs);
inline uint32_t fillIpHeader(IpHandlerArgs& ipHandlerArgs, uint32_t ip_len);
};
}

View File

@ -11,6 +11,13 @@
#include <cstdint>
#include "free_rtos/ethernet/eth_types.h"
#include "free_rtos/ethernet/eth_frame.h"
#include "free_rtos/ethernet_ip/eth_stack_iface.hpp"
struct IpHandlerArgs : public EthStackHandlerArgs {
uint32_t dest_ip;
uint8_t ip_prot_id;
Handler* ip_handler;
};
class EthIpIface {
public:
@ -18,6 +25,7 @@ public:
* Ïåðåäà÷à ïàêåòà
*/
virtual bool send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot_id, TEthPkt& pkt) = 0;
virtual bool send(IpHandlerArgs& handlerArgs) = 0;
virtual uint32_t getSelfIpAddr() = 0;

View File

@ -33,6 +33,7 @@ bool free_rtos::EthStack::init(Settings& sett) {
udp_.setPortId(eth_.mac_port_);
ip_.setSelfIpAddr(eth_.self_ip_);
ip_.setSelfMac(eth_.self_mac_);
ip_.Register(IP_PROT_ICMP, &icmp_);
ip_.Register(IP_PROT_UDP, &udp_);
@ -52,26 +53,22 @@ void free_rtos::EthStack::set_mac_address(uint64_t mac_be) {
bool free_rtos::EthStack::send_pkt(TEthMacPorts port_id, uint64_t mac_dst, uint16_t prot_id, TEthPkt& pkt)
{
TEthFrameHeader * p_eth_hdr = (TEthFrameHeader *)pkt.data;
p_eth_hdr->prot_id = prot_id;
memcpy(p_eth_hdr->mac_src, &eth_.self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(p_eth_hdr->mac_dest, &mac_dst, ETH_FRAME_MAC_ADDR_LEN_BYTES);
pkt.length+= sizeof(TEthFrameHeader);
pkt.length += sizeof(TEthFrameHeader);
return tx_flow_.send(eth_.mac_port_, pkt.data, pkt.length);
}
bool free_rtos::EthStack::send_pkt(TEthMacPorts port_id, uint16_t prot_id, uint32_t numScatterSegments)
bool free_rtos::EthStack::send_pkt(EthStackHandlerArgs& handlerArgs)
{
Handler* handler = rx_pkt_handler_.GetHandler(prot_id);
handlerArgs.port_id = eth_.mac_port_; // overwriting
if(handler == nullptr) {
DebugP_log((char*)"Error: can't find requested protocol !");
return false;
}
return tx_flow_.send(port_id, handler, numScatterSegments);
return tx_flow_.send(handlerArgs, 1);
}
void free_rtos::EthStack::rx_handler(uint8_t * p_data, uint32_t len)

View File

@ -39,7 +39,7 @@ public:
virtual void rx_handler(uint8_t * p_data, uint32_t len) override;
virtual bool send_pkt(TEthMacPorts port_id, uint64_t mac_dst, uint16_t prot_id, TEthPkt& pkt) override;
virtual bool send_pkt(TEthMacPorts port_id, uint16_t prot_id, uint32_t numScatterSegments) override;
virtual bool send_pkt(EthStackHandlerArgs& handlerArgs) override;
EthUdpServerIface * getUdpServerPtr() {return &udp_;}

View File

@ -11,8 +11,13 @@
#include <cstdint>
#include "free_rtos/ethernet/eth_types.h"
#include "free_rtos/ethernet/eth_frame.h"
#include "free_rtos/ethernet/eth_tx_flow_iface.hpp"
#include "free_rtos/handler_store/handler.hpp"
struct EthStackHandlerArgs : public TxFlowHandlerArgs {
};
class EthStackIface {
public:
/**
@ -30,7 +35,7 @@ public:
*/
virtual bool send_pkt(TEthMacPorts port_id, uint64_t mac_dst, uint16_t prot_id, TEthPkt& pkt) = 0;
virtual bool send_pkt(TEthMacPorts port_id, uint16_t prot_id, uint32_t numScatterSegments) = 0;
virtual bool send_pkt(EthStackHandlerArgs& handlerArgs) = 0;
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> eth-<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

View File

@ -25,7 +25,7 @@ free_rtos::EthUpdClient::EthUpdClient(EthIpIface& ip_iface, TEthMacPorts port_id
port_id_{port_id}
{ }
void free_rtos::EthUpdClient::put_data(uint32_t src_ip, uint8_t * p_data, uint32_t len)
void free_rtos::EthUpdClient::put_data(uint8_t * p_data, uint32_t len)
{
if ((p_data == nullptr) || (len == 0)) {
return;
@ -39,15 +39,13 @@ void free_rtos::EthUpdClient::put_data(uint32_t src_ip, uint8_t * p_data, uint32
if(new_size > max_buf_size) {
in_toggle_.exchange(toggle);
DebugP_log((char *)"Warning ! UDP client buffer overflow !\r\n");
EnetAppUtils_print("Warning ! UDP client buffer overflow !\r\n");
return;
}
buff.reserve(new_size);
buff.insert(buff.end(), p_data, p_data + len);
src_ip_ = src_ip;
in_toggle_.exchange(toggle);
rx_sem_.post();
}
@ -129,7 +127,7 @@ void free_rtos::EthUpdClient::clear()
{
buff_[out_toggle_].clear();
}
/*
bool free_rtos::EthUpdClient::write(uint32_t ip_dst_be, uint8_t * p_data, uint32_t len)
{
TUdpHeader * hdr = (TUdpHeader *)(eth_pkt_.data + sizeof(TIpHeader) + sizeof(TEthFrameHeader));
@ -170,4 +168,65 @@ bool free_rtos::EthUpdClient::write(uint32_t ip_dst_be, uint8_t * p_data, uint32
return ip_iface_.send(port_id_, ip_dst_be, IP_PROT_UDP, eth_pkt_);
}
*/
bool free_rtos::EthUpdClient::write(uint32_t ip_dst_be, uint8_t * p_data, uint32_t len)
{
UDPHandlerArgs udpHandlerArgs;
udpHandlerArgs.port_id = port_id_;
udpHandlerArgs.dest_ip = ip_dst_be;
udpHandlerArgs.ip_prot_id = IP_PROT_UDP;
udpHandlerArgs.ip_handler = this;
udpHandlerArgs.p_data = p_data;
udpHandlerArgs.len = len;
return ip_iface_.send(udpHandlerArgs);
}
uint32_t free_rtos::EthUpdClient::Sender(HandlerArgs& handlerArgs, size_t scatter_segment)
{
UDPHandlerArgs& udpHandlerArgs = static_cast<UDPHandlerArgs&>(handlerArgs); // downcasting back to derived type
TUdpHeader * hdr = (TUdpHeader *)(udpHandlerArgs.buffer + sizeof(TEthFrameHeader) + sizeof(TIpHeader));
uint8_t * p_udp_data = (uint8_t *)(udpHandlerArgs.buffer + sizeof(TEthFrameHeader) + sizeof(TIpHeader) + sizeof(TUdpHeader));
uint32_t udp_len = udpHandlerArgs.len + sizeof(TUdpHeader);
if (udpHandlerArgs.dest_ip == 0) {
udpHandlerArgs.dest_ip = src_ip_;
}
hdr->Src_port = port_src_be_;
hdr->Dst_port = port_dst_be_;
hdr->Length = BASE_SWAP16(udp_len);
hdr->Chk_sum = 0;
memcpy(p_udp_data, udpHandlerArgs.p_data, udpHandlerArgs.len);
if (use_checksum_) {
uint32_t self_ip = ip_iface_.getSelfIpAddr();
uint32_t chk_sum32 = 0;
uint8_t * const dst_ip = (uint8_t *)&udpHandlerArgs.dest_ip;
uint8_t * const src_ip = (uint8_t *)&self_ip;
for (int j = 0; j < ETH_IP_ADDR_LEN; j += 2)
{
chk_sum32 += ((uint16_t)dst_ip[j] << 8) + dst_ip[j+1];
chk_sum32 += ((uint16_t)src_ip[j] << 8) + src_ip[j+1];
}
chk_sum32 += IP_PROT_UDP + udp_len;
uint16_t chk_sum16 = eth_calcChksum(chk_sum32, (uint8_t *)hdr, udp_len);
hdr->Chk_sum = BASE_SWAP16(chk_sum16);
}
return udp_len;
}
int32_t free_rtos::EthUpdClient::Process(uint8_t * p_data, uint32_t len)
{
put_data(p_data, len);
return 0;
}

View File

@ -8,20 +8,28 @@
#ifndef FREE_RTOS_ETHERNET_IP_ETH_UDP_CLIENT_HPP_
#define FREE_RTOS_ETHERNET_IP_ETH_UDP_CLIENT_HPP_
#include "free_rtos/semaphore/semaphore.hpp"
#include "free_rtos/mutex/mutex.hpp"
#include "free_rtos/ethernet/eth_frame.h"
#include "free_rtos/ethernet_ip/eth_ip_iface.hpp"
#include "free_rtos/ethernet/eth_types.h"
#include <array>
#include <vector>
#include <atomic>
#include <iterator>
#include <cstdint>
#include <networking/enet/utils/include/enet_apputils.h>
#include "free_rtos/semaphore/semaphore.hpp"
#include "free_rtos/mutex/mutex.hpp"
#include "free_rtos/ethernet/eth_frame.h"
#include "free_rtos/ethernet_ip/eth_ip_iface.hpp"
#include "free_rtos/ethernet/eth_types.h"
#include "free_rtos/handler_store/handler_store.hpp"
namespace free_rtos {
struct UDPHandlerArgs : public IpHandlerArgs {
void * p_data;
uint32_t len;
};
enum UDPToggle : uint32_t {
UDP_BUF_0 = 0,
UDP_BUF_1,
@ -29,7 +37,7 @@ enum UDPToggle : uint32_t {
UDP_BUSY = UDP_BUF_NUM
};
class EthUpdClient {
class EthUpdClient : public Handler {
friend class EthUdpServer;
public:
@ -37,6 +45,9 @@ public:
uint16_t port_dst_be, uint16_t port_src_be,
bool use_chksum);
virtual int32_t Process(uint8_t * p_data, uint32_t len) override;
virtual uint32_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) override;
bool capture_buffer();
size_t get_data_size();
@ -70,7 +81,27 @@ public:
void clear();
private:
void put_data(uint32_t src_ip, uint8_t * p_data, uint32_t len);
const uint32_t max_buf_size = 0x1800; // 0x1800 - 6144, 0x4000 - 16384, 32768, 0x10000 - 65536, 0x11CA - 4554, 0x0BDC - 3036, 0x100000 - 1Mb
const uint16_t port_dst_be_; /// big endian
const uint16_t port_src_be_; /// big endian
const bool use_checksum_;
EthIpIface& ip_iface_;
const TEthMacPorts port_id_;
//TEthPkt eth_pkt_;
uint32_t src_ip_;
std::array<std::vector<uint8_t>, UDP_BUF_NUM> buff_;
std::atomic<UDPToggle> in_toggle_{UDPToggle::UDP_BUF_1};
UDPToggle out_toggle_{UDPToggle::UDP_BUF_0};
Semaphore rx_sem_;
void put_data(uint8_t * p_data, uint32_t len);
int32_t get_data(uint8_t * p_data, uint32_t len);
template<class T, class Allocator>
@ -92,26 +123,9 @@ private:
return size;
}
private:
const uint32_t max_buf_size = 0x4000; // 0x4000 - 16384, 32768, 0x10000 - 65536, 0x11CA - 4554, 0x0BDC - 3036, 0x100000 - 1Mb
const uint16_t port_dst_be_; /// big endian
const uint16_t port_src_be_; /// big endian
const bool use_checksum_;
EthIpIface& ip_iface_;
const TEthMacPorts port_id_;
TEthPkt eth_pkt_;
uint32_t src_ip_;
std::array<std::vector<uint8_t>, UDP_BUF_NUM> buff_;
std::atomic<UDPToggle> in_toggle_{UDPToggle::UDP_BUF_1};
UDPToggle out_toggle_{UDPToggle::UDP_BUF_0};
Semaphore rx_sem_;
void set_src_ip(uint32_t src_ip) {
src_ip_ = src_ip;
}
};
}

View File

@ -67,15 +67,15 @@ int32_t free_rtos::EthUdpServer::Process(uint8_t * p_data, uint32_t len)
memcpy(&src_ip, p_ip_hdr->ip_src, ETH_IP_ADDR_LEN);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> udp
client->put_data(src_ip, p_data + sizeof(TUdpHeader), BASE_SWAP16(hdr->Length) - sizeof(TUdpHeader));
client->set_src_ip(src_ip);
client->put_data(p_data + sizeof(TUdpHeader), BASE_SWAP16(hdr->Length) - sizeof(TUdpHeader));
rx_sem_.post();
return 0;
}
uint32_t free_rtos::EthUdpServer::Sender(uint8_t * p_data, size_t scatter_segment)
uint32_t free_rtos::EthUdpServer::Sender(HandlerArgs& handlerArgs, size_t scatter_segment)
{
return 0;
}

View File

@ -30,8 +30,7 @@ public:
bool use_chksum) override;
virtual int32_t Process(uint8_t * p_data, uint32_t len) override;
virtual uint32_t Sender(uint8_t * p_data, size_t scatter_segment) override;
virtual uint32_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) override;
virtual int32_t select(uint32_t ticks = SystemP_WAIT_FOREVER) override
{

View File

@ -11,10 +11,14 @@
#include <cstdint>
#include <cstddef>
struct HandlerArgs {
uint8_t * buffer;
};
class Handler {
public:
virtual int32_t Process(uint8_t * p_data, uint32_t len) = 0;
virtual uint32_t Sender(uint8_t * p_data, size_t scatter_segment) = 0;
virtual uint32_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) = 0;
~Handler() {};
};