dev(SF-60): Доработан канал передачи данных ethernet
This commit is contained in:
parent
9a84db4431
commit
6f3fe15497
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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(){}
|
||||
};
|
||||
|
||||
|
||||
@ -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++;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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, ð_.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)
|
||||
|
||||
@ -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_;}
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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() {};
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user