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; 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> /// <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 */ /* Initialize TX EthPkts and queue them to txFreePktInfoQ */
for (i = 0U; i < i_max; i++) 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; dma_handle_ = txChInfo.hTxCh;
EnetAppUtils_assert(txChInfo.useGlobalEvt == true); 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) if (dma_handle_ == nullptr)
{ {
@ -224,20 +224,19 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
return true; 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; return false;
} }
if (!port_data_[port_id].tx_enable) { if (!port_data_[handlerArgs.port_id].tx_enable) {
return false; return false;
} }
EnetDma_PktQ txSubmitQ; EnetDma_PktQ txSubmitQ;
EnetDma_Pkt *txPktInfo; EnetDma_Pkt *txPktInfo;
int32_t status; int32_t status;
uint32_t len;
eth_retrieveFreeTxPkts(&dma_handle_, &tx_free_pktq_); 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++) for(size_t scatter_segment = 0; scatter_segment < numScatterSegments; scatter_segment++)
{ {
len = handler->Sender(txPktInfo->sgList.list[scatter_segment].bufPtr, scatter_segment); handlerArgs.buffer = txPktInfo->sgList.list[scatter_segment].bufPtr;
txPktInfo->sgList.list[scatter_segment].segmentFilledLen = handlerArgs.stack_handler->Sender(handlerArgs, scatter_segment);
txPktInfo->sgList.list[scatter_segment].segmentFilledLen = len;
} }
txPktInfo->sgList.numScatterSegments = numScatterSegments; 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->tsInfo.txPktSeqId = 0;
txPktInfo->txPktTc = 0; /// Traffic class <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> IPv6 txPktInfo->txPktTc = 0; /// Traffic class <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> IPv6
txPktInfo->tsInfo.enableHostTxTs = false; txPktInfo->tsInfo.enableHostTxTs = false;
txPktInfo->txPortNum = (Enet_MacPort)port_id; txPktInfo->txPortNum = (Enet_MacPort)handlerArgs.port_id;
EnetDma_checkPktState(&txPktInfo->pktState, EnetDma_checkPktState(&txPktInfo->pktState,
ENET_PKTSTATE_MODULE_APP, ENET_PKTSTATE_MODULE_APP,
@ -281,7 +279,7 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, Handler *handler, uint32_t
return false; 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; return true;
} }

View File

@ -29,7 +29,7 @@ public:
void disable(TEthMacPorts port_id); 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, 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: private:
struct PortData { struct PortData {
bool tx_enable; bool tx_enable;

View File

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

View File

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

View File

@ -66,7 +66,7 @@ public:
} }
virtual int32_t Process(uint8_t *p_data, uint32_t len) 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;
void init(TEthMacPorts port_id, uint32_t period_microsec, uint32_t max_transfer_attempts) { void init(TEthMacPorts port_id, uint32_t period_microsec, uint32_t max_transfer_attempts) {
port_id_ = port_id; 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; 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; return 0;
} }

View File

@ -32,7 +32,7 @@ public:
bool try_request(uint32_t ip); bool try_request(uint32_t ip);
virtual int32_t Process(uint8_t * p_data, uint32_t len) 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;
private: private:
bool request(uint32_t ip); 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; 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; return 0;
} }

View File

@ -18,7 +18,7 @@ namespace free_rtos {
class EthIcmp : public Handler { class EthIcmp : public Handler {
public: public:
virtual int32_t Process(uint8_t * p_data, uint32_t len) 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;
uint32_t getStat() {return rx_cnt_;}; uint32_t getStat() {return rx_cnt_;};
private: 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) bool free_rtos::EthIp::send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot_id, TEthPkt& pkt)
{ {
uint64_t mac_dst; 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); 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) bool free_rtos::EthIp::Register(uint8_t prot_id, Handler * p_handler)
{ {
return handlers_.Register(prot_id, p_handler); return handlers_.Register(prot_id, p_handler);

View File

@ -8,6 +8,8 @@
#ifndef FREE_RTOS_ETHERNET_IP_ETH_IP_HPP_ #ifndef FREE_RTOS_ETHERNET_IP_ETH_IP_HPP_
#define 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/handler_store/handler_store.hpp"
#include "free_rtos/ethernet_ip/eth_stack_iface.hpp" #include "free_rtos/ethernet_ip/eth_stack_iface.hpp"
#include "free_rtos/ethernet/eth_frame.h" #include "free_rtos/ethernet/eth_frame.h"
@ -23,14 +25,15 @@ public:
EthIp(EthStackIface& eth_stack, EthArpIface& arp); EthIp(EthStackIface& eth_stack, EthArpIface& arp);
void setSelfIpAddr(uint32_t ip) {self_ip_ = ip;}; 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 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(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); bool Register(uint8_t prot_id, Handler * p_handler);
@ -40,9 +43,13 @@ private:
EthStackIface& eth_stack_; EthStackIface& eth_stack_;
EthArpIface& arp_; 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> 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 <cstdint>
#include "free_rtos/ethernet/eth_types.h" #include "free_rtos/ethernet/eth_types.h"
#include "free_rtos/ethernet/eth_frame.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 { class EthIpIface {
public: 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(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; virtual uint32_t getSelfIpAddr() = 0;

View File

@ -33,6 +33,7 @@ bool free_rtos::EthStack::init(Settings& sett) {
udp_.setPortId(eth_.mac_port_); udp_.setPortId(eth_.mac_port_);
ip_.setSelfIpAddr(eth_.self_ip_); ip_.setSelfIpAddr(eth_.self_ip_);
ip_.setSelfMac(eth_.self_mac_);
ip_.Register(IP_PROT_ICMP, &icmp_); ip_.Register(IP_PROT_ICMP, &icmp_);
ip_.Register(IP_PROT_UDP, &udp_); 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) 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; TEthFrameHeader * p_eth_hdr = (TEthFrameHeader *)pkt.data;
p_eth_hdr->prot_id = prot_id; 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_src, &eth_.self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(p_eth_hdr->mac_dest, &mac_dst, 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); 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) { return tx_flow_.send(handlerArgs, 1);
DebugP_log((char*)"Error: can't find requested protocol !");
return false;
}
return tx_flow_.send(port_id, handler, numScatterSegments);
} }
void free_rtos::EthStack::rx_handler(uint8_t * p_data, uint32_t len) 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 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, 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_;} EthUdpServerIface * getUdpServerPtr() {return &udp_;}

View File

@ -11,8 +11,13 @@
#include <cstdint> #include <cstdint>
#include "free_rtos/ethernet/eth_types.h" #include "free_rtos/ethernet/eth_types.h"
#include "free_rtos/ethernet/eth_frame.h" #include "free_rtos/ethernet/eth_frame.h"
#include "free_rtos/ethernet/eth_tx_flow_iface.hpp"
#include "free_rtos/handler_store/handler.hpp" #include "free_rtos/handler_store/handler.hpp"
struct EthStackHandlerArgs : public TxFlowHandlerArgs {
};
class EthStackIface { class EthStackIface {
public: 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, 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> * <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} 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)) { if ((p_data == nullptr) || (len == 0)) {
return; 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) { if(new_size > max_buf_size) {
in_toggle_.exchange(toggle); in_toggle_.exchange(toggle);
DebugP_log((char *)"Warning ! UDP client buffer overflow !\r\n"); EnetAppUtils_print("Warning ! UDP client buffer overflow !\r\n");
return; return;
} }
buff.reserve(new_size); buff.reserve(new_size);
buff.insert(buff.end(), p_data, p_data + len); buff.insert(buff.end(), p_data, p_data + len);
src_ip_ = src_ip;
in_toggle_.exchange(toggle); in_toggle_.exchange(toggle);
rx_sem_.post(); rx_sem_.post();
} }
@ -129,7 +127,7 @@ void free_rtos::EthUpdClient::clear()
{ {
buff_[out_toggle_].clear(); buff_[out_toggle_].clear();
} }
/*
bool free_rtos::EthUpdClient::write(uint32_t ip_dst_be, uint8_t * p_data, uint32_t len) 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)); 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_); 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_ #ifndef FREE_RTOS_ETHERNET_IP_ETH_UDP_CLIENT_HPP_
#define 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 <array>
#include <vector> #include <vector>
#include <atomic> #include <atomic>
#include <iterator> #include <iterator>
#include <cstdint> #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 { namespace free_rtos {
struct UDPHandlerArgs : public IpHandlerArgs {
void * p_data;
uint32_t len;
};
enum UDPToggle : uint32_t { enum UDPToggle : uint32_t {
UDP_BUF_0 = 0, UDP_BUF_0 = 0,
UDP_BUF_1, UDP_BUF_1,
@ -29,7 +37,7 @@ enum UDPToggle : uint32_t {
UDP_BUSY = UDP_BUF_NUM UDP_BUSY = UDP_BUF_NUM
}; };
class EthUpdClient { class EthUpdClient : public Handler {
friend class EthUdpServer; friend class EthUdpServer;
public: public:
@ -37,6 +45,9 @@ public:
uint16_t port_dst_be, uint16_t port_src_be, uint16_t port_dst_be, uint16_t port_src_be,
bool use_chksum); 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(); bool capture_buffer();
size_t get_data_size(); size_t get_data_size();
@ -70,7 +81,27 @@ public:
void clear(); void clear();
private: 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); int32_t get_data(uint8_t * p_data, uint32_t len);
template<class T, class Allocator> template<class T, class Allocator>
@ -92,26 +123,9 @@ private:
return size; return size;
} }
private: void set_src_ip(uint32_t src_ip) {
const uint32_t max_buf_size = 0x4000; // 0x4000 - 16384, 32768, 0x10000 - 65536, 0x11CA - 4554, 0x0BDC - 3036, 0x100000 - 1Mb src_ip_ = src_ip;
}
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_;
}; };
} }

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); 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->set_src_ip(src_ip);
client->put_data(src_ip, p_data + sizeof(TUdpHeader), BASE_SWAP16(hdr->Length) - sizeof(TUdpHeader)); client->put_data(p_data + sizeof(TUdpHeader), BASE_SWAP16(hdr->Length) - sizeof(TUdpHeader));
rx_sem_.post(); rx_sem_.post();
return 0; 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; return 0;
} }

View File

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

View File

@ -11,10 +11,14 @@
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
struct HandlerArgs {
uint8_t * buffer;
};
class Handler { class Handler {
public: public:
virtual int32_t Process(uint8_t * p_data, uint32_t len) = 0; 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() {}; ~Handler() {};
}; };