dev(UML-1462): Избавился от промежуточного копирования в буфер DMA при передаче

This commit is contained in:
algin 2023-06-08 12:27:49 +03:00
parent 8890af415d
commit af754ca3d2
23 changed files with 276 additions and 142 deletions

View File

@ -1,7 +1,7 @@
/*
* eth_tx_flow.cpp
*
* Created on: 7 мар. 2023 г.
* Created on: 7 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
#include "ethernet/eth_tx_flow.hpp"
@ -17,34 +17,34 @@
/*----------------------------------------------------------------------*/
/**
* Файлы генерируемые sysconfig.
* Генерируются перед сборкой и помещаются в папку <build_name>/syscfg
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> sysconfig.
* <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><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <build_name>/syscfg
*/
#include "ti_enet_config.h"
/*----------------------------------------------------------------------*/
/**
* Выделяет память под сводобные пакеты и кладет их в очередь p_packet_queue
* <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><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p_packet_queue
*/
static void eth_initTxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue)
{
EnetDma_Pkt *pPktInfo;
uint32_t i;
/// Максимальное количество пакетов
/// <EFBFBD><EFBFBD><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);
/* Initialize TX EthPkts and queue them to txFreePktInfoQ */
for (i = 0U; i < i_max; i++)
{
/// Выделяем память
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pPktInfo = EnetMem_allocEthPkt(appPriv,
ENET_MEM_LARGE_POOL_PKT_SIZE,
ENETDMA_CACHELINE_ALIGNMENT);
EnetAppUtils_assert(pPktInfo != NULL);
/// Указываем что этот пакет свободен
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ENET_UTILS_SET_PKT_APP_STATE(&pPktInfo->pktState, ENET_PKTSTATE_APP_WITH_FREEQ);
/// Кладем пакет в очередь p_packet_queue
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p_packet_queue
EnetQueue_enq(p_packet_queue, &pPktInfo->node);
}
@ -61,11 +61,11 @@ static uint32_t eth_retrieveFreeTxPkts(EnetDma_TxChHandle * p_handle, EnetDma_Pk
EnetQueue_initQ(&txFreeQ);
/// Извлекаем пакеты которые были успешно переданы из очереди завершения передачи
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
status = EnetDma_retrieveTxPktQ(*p_handle, &txFreeQ);
if (status == ENET_SOK)
{
/// Количество пакетов в очереди
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
txFreeQCnt = EnetQueue_getQCount(&txFreeQ);
pktInfo = (EnetDma_Pkt *)EnetQueue_deq(&txFreeQ);
@ -76,9 +76,9 @@ static uint32_t eth_retrieveFreeTxPkts(EnetDma_TxChHandle * p_handle, EnetDma_Pk
ENET_PKTSTATE_APP_WITH_DRIVER,
ENET_PKTSTATE_APP_WITH_FREEQ);
/// Положить пакет в очередь свободных пакетов txFreePktInfoQ
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> txFreePktInfoQ
EnetQueue_enq(p_queque, &pktInfo->node);
pktInfo = (EnetDma_Pkt *)EnetQueue_deq(&txFreeQ); /// Взять следующий свободный пакет
pktInfo = (EnetDma_Pkt *)EnetQueue_deq(&txFreeQ); /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
}
}
else
@ -86,7 +86,7 @@ static uint32_t eth_retrieveFreeTxPkts(EnetDma_TxChHandle * p_handle, EnetDma_Pk
EnetAppUtils_print("retrieveFreeTxPkts() failed to retrieve pkts: %d\r\n", status);
}
return txFreeQCnt; /// Количество свободных пакетов
return txFreeQCnt; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
free_rtos::EthTxFlow::EthTxFlow() :
@ -174,18 +174,18 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
int32_t status;
/*
* Обнаруживает свободные пакеты в драйвере enet и кладет их в очередь свободных пакетов txFreePktInfoQ
* <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> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> enet <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><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> txFreePktInfoQ
*/
eth_retrieveFreeTxPkts(&dma_handle_, &tx_free_pktq_);
/// Инициализируем поля txSubmitQ
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> txSubmitQ
EnetQueue_initQ(&txSubmitQ);
/* Забрать из очереди один свободный пакет TX Eth */
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> TX Eth */
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
if (txPktInfo != NULL)
{
///Копируем данные пакета в буфер
///<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
memcpy(txPktInfo->sgList.list[0].bufPtr, p_data, len);
txPktInfo->sgList.list[0].segmentFilledLen = len;
@ -193,7 +193,7 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
txPktInfo->chkSumInfo = 0U;
txPktInfo->appPriv = nullptr;
txPktInfo->tsInfo.txPktSeqId = 0;
txPktInfo->txPktTc = 0; /// Traffic class нужен для IPv6
txPktInfo->txPktTc = 0; /// Traffic class <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> IPv6
txPktInfo->tsInfo.enableHostTxTs = false;
txPktInfo->txPortNum = (Enet_MacPort)port_id;
@ -202,7 +202,7 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
ENET_PKTSTATE_APP_WITH_FREEQ,
ENET_PKTSTATE_APP_WITH_DRIVER);
/// Кладем пакет txPktInfo в очередь txSubmitQ
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> txPktInfo <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> txSubmitQ
EnetQueue_enq(&txSubmitQ, &txPktInfo->node);
}
else
@ -211,7 +211,7 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
return false;
}
/// Кладем очередь в очередь DMA
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DMA
status = EnetDma_submitTxPktQ(dma_handle_, &txSubmitQ);
if (status != ENET_SOK)
{
@ -219,9 +219,69 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
return false;
}
++port_data_[port_id].tx_pkt_counter; /// Счетчик переданных пакетов
++port_data_[port_id].tx_pkt_counter; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return true;
}
bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, Handler *handler, uint32_t numScatterSegments)
{
if (port_id >= e_ethMacTotal) {
return false;
}
if (!port_data_[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_);
EnetQueue_initQ(&txSubmitQ);
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
if (txPktInfo != NULL)
{
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;
}
txPktInfo->sgList.numScatterSegments = numScatterSegments;
txPktInfo->chkSumInfo = 0U;
txPktInfo->appPriv = nullptr;
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;
EnetDma_checkPktState(&txPktInfo->pktState,
ENET_PKTSTATE_MODULE_APP,
ENET_PKTSTATE_APP_WITH_FREEQ,
ENET_PKTSTATE_APP_WITH_DRIVER);
EnetQueue_enq(&txSubmitQ, &txPktInfo->node);
}
else
{
EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", id_);
return false;
}
status = EnetDma_submitTxPktQ(dma_handle_, &txSubmitQ);
if (status != ENET_SOK)
{
EnetAppUtils_print("tx_flow %u: Failed to submit TX pkt queue: %d\r\n", id_, status);
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>
return true;
}

View File

@ -1,7 +1,7 @@
/*
* eth_tx_flow.hpp
*
* Created on: 7 ìàð. 2023 ã.
* Created on: 7 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -12,6 +12,7 @@
#include <networking/enet/core/include/core/enet_dma.h>
#include "ethernet/eth_tx_flow_iface.hpp"
#include "handler_store/handler_store.hpp"
namespace free_rtos {
@ -28,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;
private:
struct PortData {
bool tx_enable;
@ -40,8 +41,8 @@ private:
//-------------------------------------------------
uint32_t tx_ch_num_;
EnetDma_TxChHandle dma_handle_; /// Ïåðåäàþùèé êàíàë DMA
EnetDma_PktQ tx_free_pktq_; /// Î÷åðåäü ñâîáîäíûõ ïàêåòîâ
EnetDma_TxChHandle dma_handle_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> DMA
EnetDma_PktQ tx_free_pktq_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
PortData port_data_[e_ethMacTotal];
};

View File

@ -1,7 +1,7 @@
/*
* eth_tx_iface.hpp
*
* Created on: 13 ìàð. 2023 ã.
* Created on: 13 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -10,10 +10,12 @@
#include <cstdint>
#include "ethernet/eth_types.h"
#include "handler_store/handler_store.hpp"
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 ~EthTxFlowIface(){}
};

View File

@ -85,8 +85,9 @@ public:
custom_promise::WritePromise<DataTypes...> promise{offset, data...};
mutex_write_.lock();
//last_write_ = (*last_write_) + &promise;
queue_write_ + promise;
mutex_write_.unlock();
promise.get_future().get();
@ -97,8 +98,9 @@ public:
custom_promise::ReadPromise<DataTypes...> promise{offset, data...};
mutex_read_.lock();
//last_read_ = (*last_read_) + &promise;
queue_read_ + promise;
mutex_read_.unlock();
promise.get_future().get();
@ -108,7 +110,6 @@ public:
void pdo_write_async(custom_promise::IPromise& promise) {
mutex_write_.lock();
//last_write_ = (*last_write_) + &promise;
queue_write_ + promise;
mutex_write_.unlock();
@ -118,7 +119,6 @@ public:
void pdo_read_async(custom_promise::IPromise& promise) {
mutex_read_.lock();
//last_read_ = (*last_read_) + &promise;
queue_read_ + promise;
mutex_read_.unlock();
@ -135,9 +135,6 @@ private:
custom_promise::WritePromise<> queue_write_{0};
custom_promise::ReadPromise<> queue_read_{0};
//custom_promise::IPromise *last_write_{&queue_write_};
//custom_promise::IPromise *last_read_{&queue_read_};
void wait_op();
void process_write_queue(uint8_t* process_data, uint32_t len);

View File

@ -38,8 +38,6 @@ struct DatagramPackFunctor : public PackFunctor {
template<typename CommandT, typename... DataTypes>
void operator()(std::vector< datagram::EcatDatagram<CommandT, DataTypes...> >& data) {
for(uint16_t i = 1; i < data.size(); i++) {
data[i - 1] + data[i];
raw = data[i - 1].pack(raw);
}
@ -94,8 +92,8 @@ public:
for_each(data_tuple_, functor);
sem_.post();
ready_ = true;
sem_.post();
}
void unpack(uint8_t* raw) {
@ -103,8 +101,8 @@ public:
for_each(data_tuple_, functor);
sem_.post();
ready_ = true;
sem_.post();
}
private:

View File

@ -56,6 +56,12 @@ public:
return next;
}
void detach() {
more_ = ec_moredatagrams::EC_MOREDATAGRAMS_LAST;
queue_entity_.detach();
}
virtual uint8_t* pack(uint8_t *raw) = 0;
virtual uint8_t* unpack(uint8_t *raw) = 0;

View File

@ -28,15 +28,20 @@ public:
return next_;
}
size_t get_size() {
return size_;
}
void detach() {
next_ = nullptr;
first_ = this;
last_ = this;
size_ = 1;
}
QueueEntity& operator+(QueueEntity& next) {
attach(next);
//set_next(next);
return next;
@ -49,6 +54,8 @@ private:
QueueEntity *first_{this};
QueueEntity *last_{this};
size_t size_{1};
void set_next(QueueEntity &next) {
next_ = &next;
}
@ -69,6 +76,8 @@ private:
last_->set_next(next);
//last_ = next.get_last();
last_ = &next;
size_++;
}
return first_;

View File

@ -12,74 +12,76 @@ namespace free_rtos {
namespace telegram {
int32_t EcatTelegram::Process(uint8_t *p_data, uint32_t len) {
//buffer_in_.length = len + sizeof(TEthFrameHeader);
//memcpy(buffer_in_.data, p_data - sizeof(TEthFrameHeader), buffer_in_.length);
if(datagram_queue_ == nullptr) {
return 0;
}
unpack(p_data);
datagram_queue_ = nullptr;
rx_sem_.post();
return 0;
}
void EcatTelegram::pack() {
TEthFrameHeader *p_eth_hdr = new(buffer_out_.data) TEthFrameHeader{ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
ETH_PROT_ECAT_LE};
TEcatFrameHeader *p_hdr = new(buffer_out_.data + sizeof(TEthFrameHeader)) TEcatFrameHeader{ .bits{
.length = 0,
.type = static_cast<uint16_t>(ec_network::PROTOCOL_TYPE)}};
uint8_t *p_datagram_first = buffer_out_.data + sizeof(TEthFrameHeader) + sizeof(TEcatFrameHeader);
uint32_t EcatTelegram::Sender(uint8_t *p_data, size_t scatter_segment) {
uint8_t *raw = pack(p_data);
return raw - p_data;
}
uint8_t* EcatTelegram::pack(uint8_t *raw) {
TEthFrameHeader *p_eth_hdr = new(raw) TEthFrameHeader{ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
ETH_PROT_ECAT_LE };
TEcatFrameHeader *p_hdr = new(raw + sizeof(TEthFrameHeader)) TEcatFrameHeader{ .bits{ .length = 0,
.type = static_cast<uint16_t>(ec_network::PROTOCOL_TYPE) } };
uint8_t *p_datagram_first = raw + sizeof(TEthFrameHeader) + sizeof(TEcatFrameHeader);
uint8_t *p_datagram_last = p_datagram_first;
queue::QueueEntity<datagram::IEcatDatagram> *next = datagram_queue_;
datagram::IEcatDatagram *next = datagram_queue_;
(void)p_eth_hdr;
(void)p_hdr;
while(next != nullptr) {
p_datagram_last = next->get_data()->pack(p_datagram_last);
p_datagram_last = next->pack(p_datagram_last);
next = next->get_next();
}
p_hdr->bits.length = p_datagram_last - p_datagram_first;
buffer_out_.length = sizeof(TEthFrameHeader) + sizeof(TEcatFrameHeader) + p_hdr->bits.length;
//buffer_out_.length = sizeof(TEthFrameHeader) + sizeof(TEcatFrameHeader) + p_hdr->bits.length;
return p_datagram_last;
}
void EcatTelegram::unpack(uint8_t *raw) {
uint8_t* EcatTelegram::unpack(uint8_t *raw) {
TEthFrameHeader *p_eth_hdr = reinterpret_cast<TEthFrameHeader*>(raw);
TEcatFrameHeader *p_hdr = reinterpret_cast<TEcatFrameHeader*>(raw + sizeof(TEthFrameHeader));
uint8_t *p_datagram_first = raw + sizeof(TEthFrameHeader) + sizeof(TEcatFrameHeader);
uint8_t *p_datagram_last = p_datagram_first;
queue::QueueEntity<datagram::IEcatDatagram> *next = datagram_queue_;
datagram::IEcatDatagram *next = datagram_queue_;
(void)p_eth_hdr;
(void)p_hdr;
while(next != nullptr) {
p_datagram_last = next->get_data()->unpack(p_datagram_last);
p_datagram_last = next->unpack(p_datagram_last);
next = next->get_next();
}
return p_datagram_last;
}
void EcatTelegram::transfer(datagram::IEcatDatagram& first) {
datagram_queue_ = &first.get_queue_entity(); // TODO: Доделать добавление в очередь более одного элемента
datagram_queue_ = &first;
pack();
bool stat = tx_flow_.send(port_id_, buffer_out_.data, buffer_out_.length);
//pack();
//bool stat = tx_flow_.send(port_id_, buffer_out_.data, buffer_out_.length);
bool stat = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1);
if(stat == false) {
return;
}
rx_sem_.pend();
//unpack(first);
datagram_queue_ = nullptr;
}
}

View File

@ -20,14 +20,15 @@ class EcatTelegram : public Handler {
public:
EcatTelegram(Eth& eth)
: eth_{eth}
, tx_flow_{*eth.getTxFlowPtr()} {
eth_.getEthStackPtr()->Register(ETH_PROT_ECAT_LE, this);
}
, tx_flow_{*eth.getTxFlowPtr()}
, eth_stack_{*eth.getEthStackPtr()} { }
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;
void init(TEthMacPorts port_id) {
port_id_ = port_id;
eth_.getEthStackPtr()->Register(ETH_PROT_ECAT_LE, this);
}
void transfer(datagram::IEcatDatagram& first);
@ -35,16 +36,17 @@ public:
private:
Eth& eth_;
EthTxFlowIface& tx_flow_;
EthStackIface& eth_stack_;
TEthMacPorts port_id_;
free_rtos::Semaphore rx_sem_;
queue::QueueEntity<datagram::IEcatDatagram> *datagram_queue_{nullptr};
datagram::IEcatDatagram *datagram_queue_{nullptr};
TEthPkt buffer_out_;
//TEthPkt buffer_out_;
void pack();
void unpack(uint8_t *raw);
uint8_t* pack(uint8_t *raw);
uint8_t* unpack(uint8_t *raw);
};
}

View File

@ -1,7 +1,7 @@
/*
* eth_arp.cpp
*
* Created on: 13 мар. 2023 г.
* Created on: 13 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
#include "ethernet_ip/eth_arp.hpp"
@ -17,7 +17,7 @@ void free_rtos::clock_timeout(ClockP_Object * obj, void * arg)
{
EthArp * p_arp = ( EthArp *)arg;
/// Запрашиваем собственный ip
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip
if (p_arp->tmrGratuitous_.tick(100))
{
if (p_arp->table_mac_.empty()) {
@ -37,7 +37,7 @@ void free_rtos::clock_timeout(ClockP_Object * obj, void * arg)
}
else
{
p_arp->request(item.first); /// Запрос mac адреса по ip
p_arp->request(item.first); /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> ip
}
}
}
@ -58,9 +58,9 @@ bool free_rtos::EthArp::init(TEthMacPorts eth_port_id, uint64_t self_mac, uint32
init_request_pkt(self_mac_, self_ip_);
clock_.init(100, free_rtos::clock_timeout, this); /// 100мс
clock_.init(100, free_rtos::clock_timeout, this); /// 100<EFBFBD><EFBFBD>
tmrGratuitous_.start(1000); /// 1 раз в секунду
tmrGratuitous_.start(1000); /// 1 <EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
clock_.start();
@ -71,7 +71,7 @@ void free_rtos::EthArp::init_request_pkt(uint64_t self_mac, uint32_t self_ip)
{
TArpHeader * arp_hdr = (TArpHeader *)(request_pkt_.data + sizeof(TEthFrameHeader));
/// Заполняем заголовок ARP
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ARP
memcpy(arp_hdr->ar_sha, &self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memset(arp_hdr->ar_tha, 0, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(arp_hdr->ar_spa, &self_ip_, ETH_IP_ADDR_LEN);
@ -89,12 +89,12 @@ bool free_rtos::EthArp::request(uint32_t ip)
{
TArpHeader * arp_hdr = (TArpHeader *)(request_pkt_.data + sizeof(TEthFrameHeader));
/// Копируем ip-адрес для запроса
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip-<2D><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memcpy(arp_hdr->ar_tpa, &ip, ETH_IP_ADDR_LEN);
request_pkt_.length = sizeof(TArpHeader);
/// Широковещательный запрос
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return eth_stack_.send_pkt(eth_port_id_, ETH_FRAME_MAC_ADDR_BROADCAST, ETH_PROT_ARP_BE, request_pkt_);
}
@ -111,16 +111,16 @@ bool free_rtos::EthArp::try_request(uint32_t ip)
{
p_ip_req_data = &item->second;
if (p_ip_req_data->mac != 0) {
return true; /// Мак адрес уже известен
return true; /// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
else if (p_ip_req_data->tmr.is_started()) {
return true; /// Опрос уже идет
return true; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
}
}
p_ip_req_data->attemps = 0;
p_ip_req_data->tmr.start(1000); /// Опрос 1 разв в сек
p_ip_req_data->tmr.start(1000); /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD>
return request(ip);
}
@ -172,13 +172,13 @@ int32_t free_rtos::EthArp::Process(uint8_t * p_data, uint32_t len)
memcpy(&ip_sender, arp_hdr->ar_spa, ETH_IP_ADDR_LEN);
/**
* если ip == 0, то это запрос "Who has....".
* Отвечать на него не нужно.
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip == 0, <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "Who has....".
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
*/
if (ip_sender == 0) {
return 0;
}
/// Добавляем запись в arp-таблицу
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> arp-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
add(mac_sender, ip_sender);
if ( type == arp_opr_be_[e_oprRequest])
@ -188,19 +188,24 @@ int32_t free_rtos::EthArp::Process(uint8_t * p_data, uint32_t len)
if (ip_target == self_ip_)
{
/// Тип пакета - ответ
/// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD>
arp_hdr->ar_op = arp_opr_be_[e_oprReply];
/// Меняем местами mac адрес
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac <20><><EFBFBD><EFBFBD><EFBFBD>
memcpy(arp_hdr->ar_tha, arp_hdr->ar_sha, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(arp_hdr->ar_sha, &self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
/// Меняем местами ip адрес
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip <20><><EFBFBD><EFBFBD><EFBFBD>
memcpy(arp_hdr->ar_tpa, arp_hdr->ar_spa, ETH_IP_ADDR_LEN);
memcpy(arp_hdr->ar_spa, &self_ip_, ETH_IP_ADDR_LEN);
/// Отправляем размер пакета для отправки
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return len;
}
}
return 0;
}
uint32_t free_rtos::EthArp::Sender(uint8_t * p_data, size_t scatter_segment)
{
}

View File

@ -1,7 +1,7 @@
/*
* eth_arp.hpp
*
* Created on: 13 ìàð. 2023 ã.
* Created on: 13 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -32,6 +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;
private:
bool request(uint32_t ip);
@ -48,9 +49,9 @@ private:
};
struct ArpIpReqData {
uint64_t mac = 0; /// Ìàê-àäðåñ
uint32_t attemps = 0; /// Êîëèò÷åñòâî ïîïûòîê çàïðîñà
TimerSw tmr; /// Òàéìåð çàïðîñîâ
uint64_t mac = 0; /// <EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD>
uint32_t attemps = 0; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TimerSw tmr; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
static const uint32_t pkt_len = 42;
@ -59,8 +60,8 @@ private:
TEthPkt request_pkt_;
std::map<uint64_t, uint32_t> table_mac_; /// Êëþ÷ mac, çíà÷åíèå ip
std::map<uint32_t, ArpIpReqData> table_ip_; /// Êëþ÷ ip,
std::map<uint64_t, uint32_t> table_mac_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip
std::map<uint32_t, ArpIpReqData> table_ip_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip,
uint64_t self_mac_;
uint32_t self_ip_;

View File

@ -1,7 +1,7 @@
/*
* eth_icmp.cpp
*
* Created on: 14 ìàð. 2023 ã.
* Created on: 14 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
#include "ethernet_ip/eth_icmp.hpp"
@ -40,3 +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)
{
}

View File

@ -1,7 +1,7 @@
/*
* eth_icmp.hpp
*
* Created on: 14 ìàð. 2023 ã.
* Created on: 14 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -11,12 +11,14 @@
#include "handler_store/handler.hpp"
#include <cstdint>
#include <cstddef>
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;
uint32_t getStat() {return rx_cnt_;};
private:

View File

@ -1,7 +1,7 @@
/*
* eth_ip.cpp
*
* Created on: 13 мар. 2023 г.
* Created on: 13 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
#include "ethernet_ip/eth_ip.hpp"
@ -70,15 +70,20 @@ int32_t free_rtos::EthIp::Process(uint8_t * p_data, uint32_t len)
return reply;
}
uint32_t free_rtos::EthIp::Sender(uint8_t * p_data, size_t scatter_segment)
{
}
bool free_rtos::EthIp::send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot_id, TEthPkt& pkt)
{
uint64_t mac_dst;
/// Берем mac-адрес из arp таблицы
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac-<2D><><EFBFBD><EFBFBD><EFBFBD> <20><> arp <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!arp_.getMacAddr(dest_ip, mac_dst)) {
/*
* Если записи в arp-таблице нет, то автоматом запрашивает arp-запрос
* (этот запрос внутри функции getMacAddr)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> arp-<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><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arp-<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><EFBFBD> getMacAddr)
*/
return false;
}
@ -118,7 +123,7 @@ bool free_rtos::EthIp::send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot
ip_header->ip_sum = BASE_SWAP16(cksum);
/// Отправка данных
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return eth_stack_.send_pkt(port_id, mac_dst, ETH_PROT_IP_BE, pkt);
}

View File

@ -1,7 +1,7 @@
/*
* eth_ip.hpp
*
* Created on: 13 ìàð. 2023 ã.
* Created on: 13 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -28,6 +28,8 @@ 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 bool send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot_id, TEthPkt& pkt) override;
bool Register(uint8_t prot_id, Handler * p_handler);
@ -38,9 +40,9 @@ private:
EthStackIface& eth_stack_;
EthArpIface& arp_;
uint16_t ip_indet_; /// Ïîëå ip_id
uint16_t ip_indet_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip_id
uint32_t self_ip_; /// Ñîáñòâåííûé ip-àäðåñ
uint32_t self_ip_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip-<2D><><EFBFBD><EFBFBD><EFBFBD>
};
}

View File

@ -1,7 +1,7 @@
/*
* eth_stack.cpp
*
* Created on: 14 мар. 2023 г.
* Created on: 14 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
#include "ethernet_ip/eth_stack.hpp"
@ -61,18 +61,29 @@ bool free_rtos::EthStack::send_pkt(TEthMacPorts port_id, uint64_t mac_dst, uint1
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)
{
Handler* handler = rx_pkt_handler_.GetHandler(prot_id);
if(handler == nullptr) {
return false;
}
return tx_flow_.send(port_id, handler, numScatterSegments);
}
void free_rtos::EthStack::rx_handler(uint8_t * p_data, uint32_t len)
{
/// Минимальная длина eth-пакета = 60 байт
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> eth-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> = 60 <20><><EFBFBD><EFBFBD>
if ( len < ETH_FRAME_MIN_LEN) {
return;
}
/// Считываем адрес назначения
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint64_t dest_addr = *((uint64_t*)p_data);
dest_addr &= ETH_FRAME_MAC_ADDR_MASK; /// оставляем 6 младших байт
dest_addr &= ETH_FRAME_MAC_ADDR_MASK; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 6 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// Реагируем только когда мак адрес широковещательный или наш собственный
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ((ETH_FRAME_MAC_ADDR_BROADCAST != dest_addr) &&
(eth_.self_mac_ != dest_addr)) {
return;
@ -80,21 +91,21 @@ void free_rtos::EthStack::rx_handler(uint8_t * p_data, uint32_t len)
TEthFrameHeader * p_eth_hdr = (TEthFrameHeader *)p_data;
/// Вызываем обработчик
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int32_t reply_len = rx_pkt_handler_.Process(p_eth_hdr->prot_id,
p_data + sizeof(TEthFrameHeader),
len - sizeof(TEthFrameHeader));
/// Отправляем ответ
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
if (reply_len > 0) {
/// Заменяем адрес назначения mac-адресом отправителя
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memcpy(p_eth_hdr->mac_dest, p_eth_hdr->mac_src, ETH_FRAME_MAC_ADDR_LEN_BYTES);
/// Заменяем адрес источника своим mac-адресом
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> mac-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memcpy(p_eth_hdr->mac_src, &eth_.self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
reply_len+=sizeof(TEthFrameHeader);
/// Отправляем данные
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tx_flow_.send(eth_.mac_port_, p_data, reply_len);
}
}

View File

@ -1,7 +1,7 @@
/*
* eth_stack.hpp
*
* Created on: 14 мар. 2023 г.
* Created on: 14 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -39,17 +39,18 @@ 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;
EthUdpServerIface * getUdpServerPtr() {return &udp_;}
/*
* Регистрация обработчика протокола на уровне ethernet
* <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><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ethernet
*/
virtual bool Register(uint32_t prot_id, Handler * p_handler) override;
private:
struct EthData {
uint64_t self_mac_; /// Собственный мак адрес
uint64_t self_mac_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
TEthMacPorts mac_port_;
uint32_t self_ip_;
};

View File

@ -1,7 +1,7 @@
/*
* eth_stack_iface.hpp
*
* Created on: 14 мар. 2023 г.
* Created on: 14 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -16,22 +16,24 @@
class EthStackIface {
public:
/**
* Установка собственного mac-адреса
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac-<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void set_mac_address(uint64_t mac_addr_be) = 0;
/**
* Обработчик eth пакетов
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> eth <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void rx_handler(uint8_t * p_data, uint32_t len) = 0;
/**
* Передача пакета
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
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;
/**
* Регистрация обработчика eth-пакета
* <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>
*/
virtual bool Register(uint32_t prot_id, Handler * p_handler) = 0;

View File

@ -1,7 +1,7 @@
/*
* eth_udp.cpp
*
* Created on: 15 мар. 2023 г.
* Created on: 15 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
#include "ethernet_ip/eth_udp_server.hpp"
@ -23,7 +23,7 @@ std::shared_ptr<free_rtos::EthUpdClient> free_rtos::EthUdpServer::createClient(u
port_dst = BASE_SWAP16(port_dst);
port_src = BASE_SWAP16(port_src);
/// Клиент уже зарегистрирован на этот порт
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (connections_.count(port_dst)) {
return nullptr;
}
@ -52,7 +52,7 @@ int32_t free_rtos::EthUdpServer::Process(uint8_t * p_data, uint32_t len)
auto item = connections_.find(port);
/// Такой порт не зарегистрирован
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (item == connections_.end()) {
return 0;
}
@ -65,11 +65,14 @@ 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);
/// Копируем данные udp
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> udp
client->put_data(src_ip, p_data + sizeof(TUdpHeader), len - sizeof(TUdpHeader));
return 0;
}
uint32_t free_rtos::EthUdpServer::Sender(uint8_t * p_data, size_t scatter_segment)
{
}

View File

@ -1,7 +1,7 @@
/*
* eth_udp.hpp
*
* Created on: 15 ìàð. 2023 ã.
* Created on: 15 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -28,15 +28,17 @@ 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;
private:
EthIpIface& ip_iface_;
TEthMacPorts port_id_;
std::map<uint16_t, std::shared_ptr<EthUpdClient>> connections_; /// Êëþ÷ - ïîðò íàçíà÷åíèÿ
std::map<uint16_t, std::shared_ptr<EthUpdClient>> connections_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
///HandlerStore handlers_; /// Îáðàáîò÷èêè udp-äàííûõ
///HandlerStore handlers_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> udp-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
}

View File

@ -1,7 +1,7 @@
/*
* handler_obj.hpp
*
* Created on: 6 ìàð. 2023 ã.
* Created on: 6 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -9,10 +9,12 @@
#define FREE_RTOS_HANDLER_STORE_HANDLER_HPP_
#include <cstdint>
#include <cstddef>
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;
~Handler() {};
};

View File

@ -1,7 +1,7 @@
/*
* handler_store.cpp
*
* Created on: 6 мар. 2023 г.
* Created on: 6 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
#include "handler_store/handler_store.hpp"
@ -12,10 +12,10 @@ bool HandlerStore::Register(uint32_t prot_id, Handler * p_handler) {
}
if (handlers_.count(prot_id)) {
return false; /// Обработчик уже зарегистрирован
return false; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
/// Регистрация обработчика
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
handlers_[prot_id] = p_handler;
return true;
@ -33,14 +33,29 @@ int32_t HandlerStore::Process(uint32_t prot_id, uint8_t * p_data, uint32_t len)
auto item = handlers_.find(prot_id);
/// Обработчик не зарегистрирован
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (item == handlers_.end()) {
return 0;
}
/// Вызов обработчика
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return handlers_.at(prot_id)->Process(p_data, len);
}
Handler* HandlerStore::GetHandler(uint32_t prot_id)
{
if (handlers_.empty()) {
return nullptr;
}
auto item = handlers_.find(prot_id);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (item == handlers_.end()) {
return nullptr;
}
/// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return handlers_.at(prot_id);
}

View File

@ -1,7 +1,7 @@
/*
* handler_store.hpp
*
* Created on: 6 ìàð. 2023 ã.
* Created on: 6 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
* Author: sychev
*/
@ -17,15 +17,17 @@
class HandlerStore {
public:
/***
* Ðåãèñòðàöèÿ îáðàáîò÷èêà
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
bool Register(uint32_t prot_id, Handler * p_handler);
/***
* Îáðàáîòêà ïðèøåäøåãî ïàêåòà
* <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>
*/
int32_t Process(uint32_t prot_id, uint8_t * p_data, uint32_t len);
Handler* GetHandler(uint32_t prot_id);
private:
std::map<uint32_t, Handler *> handlers_; /// Îáðàáîò÷èêè ïàêåòîâ Ethernet
std::map<uint32_t, Handler *> handlers_; /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ethernet
};