dev(): Доработана и отрефакторена передача и прием данных

This commit is contained in:
algin 2024-02-16 17:06:59 +03:00
parent 24f5a680fa
commit 29e5c3e92f
5 changed files with 185 additions and 202 deletions

View File

@ -161,7 +161,6 @@ bool free_rtos::Eth::host_init()
void free_rtos::Eth::link_task()
{
bool linkUp;
Enet_MacPort macPort;
Enet_IoctlPrms prms;
IcssgMacPort_SetPortStateInArgs setPortStateInArgs;
@ -170,16 +169,15 @@ void free_rtos::Eth::link_task()
{
for (int i = 0; i < macPortNum_; ++i)
{
macPort = macPort_[i];
linkUp = false;
ENET_IOCTL_SET_INOUT_ARGS(&prms, &macPort, &linkUp);
ENET_IOCTL_SET_INOUT_ARGS(&prms, &macPort_[i], &linkUp);
status = eth_ioctl(handleInfo_.hEnet, core_id_, ENET_PER_IOCTL_IS_PORT_LINK_UP, &prms);
if (status != ENET_SOK)
{
EnetAppUtils_print("link_task: %s: Failed to get port %u link status: %d\r\n",
name_.c_str(), ENET_MACPORT_ID(macPort), status);
name_.c_str(), ENET_MACPORT_ID(macPort_[i]), status);
linkUp = false;
continue;
}
@ -187,11 +185,11 @@ void free_rtos::Eth::link_task()
if (linkUp_[i] != linkUp)
{
EnetAppUtils_print("link_task: %s: Port %u link is %s\r\n",
name_.c_str(), ENET_MACPORT_ID(macPort), linkUp ? "up" : "down");
name_.c_str(), ENET_MACPORT_ID(macPort_[i]), linkUp ? "up" : "down");
if (linkUp)
{
EnetAppUtils_print("link_task: %s: Set port state to 'Forward'\r\n", name_.c_str());
setPortStateInArgs.macPort = macPort;
setPortStateInArgs.macPort = macPort_[i];
setPortStateInArgs.portState = ICSSG_PORT_STATE_FORWARD;
ENET_IOCTL_SET_IN_ARGS(&prms, &setPortStateInArgs);
@ -215,34 +213,34 @@ void free_rtos::Eth::link_task()
}
/// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD> SWITCH)
if (!tx_flow_.open(i, ENET_DMA_TX_CH0))
if (!tx_flow_.open((TEthMacPorts)macPort_[i], ENET_DMA_TX_CH0))
{
EnetAppUtils_print("link_task: %s: Failed to open tx flow\n", name_.c_str());
continue;
}
if (!rx_flow_[i].open(i, ENET_DMA_RX_CH0 + i, rxTaskPriority_[i], rxTaskStackSize_[i]))
if (!rx_flow_[i].open((TEthMacPorts)macPort_[i], ENET_DMA_RX_CH0 + i, rxTaskPriority_[i], rxTaskStackSize_[i]))
{
EnetAppUtils_print("link_task: %s: Failed to open rx flow: %u\n", name_.c_str(), i);
continue;
}
/// e_ethMac0
if (i == e_ethMac0)
if (macPort_[i] == ENET_MAC_PORT_1)
{
if (!host_init()) {
EnetAppUtils_print("link_task: %s: Failed to init host\r\n", name_.c_str());
continue;
}
}
else if (i == e_ethMac1) {
else if (macPort_[i] == ENET_MAC_PORT_2) {
//rx_flow_[i].set_passive(); /// <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
tx_flow_.enable((TEthMacPorts)i);
tx_flow_.enable((TEthMacPorts)macPort_[i]);
}
else {
tx_flow_.disable((TEthMacPorts)i);
tx_flow_.disable((TEthMacPorts)macPort_[i]);
}
linkUp_[i] = linkUp;

View File

@ -34,6 +34,7 @@ void free_rtos::rxIsrHandler(void *appData)
return;
}
rx_flow->retrieveReadyRxPktQ();
rx_flow->sem_[EthRxFlow::e_signalRxPkt].post();
}
@ -50,7 +51,7 @@ free_rtos::EthRxFlow::EthRxFlow(TEthFrameMacAddr& mac_addr, EthStackIface& eth_s
eth_stack_{eth_stack},
passive_mode_{false}
{
EnetQueue_initQ(&rx_free_pktq_);
EnetQueue_initQ(&rx_ready_pktq_);
}
void free_rtos::EthRxFlow::initRxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue, uint32_t qCount)
@ -82,30 +83,24 @@ void free_rtos::EthRxFlow::initRxFreePktQ(void * appPriv, EnetDma_PktQ * p_packe
EnetAppUtils_assert(EnetQueue_getQCount(&rxReadyQ) == 0U);
}
void free_rtos::EthRxFlow::submitFreeRxPkts(uint32_t qCount)
void free_rtos::EthRxFlow::retrieveReadyRxPktQ() {
int32_t status = EnetDma_retrieveRxPktQ(dma_handle_, &rx_ready_pktq_);
EnetAppUtils_assert(status == ENET_SOK);
}
void free_rtos::EthRxFlow::submitFreeRxPktQ(EnetDma_PktQ * p_packet_queue)
{
EnetDma_PktQ rxSubmitQ;
EnetDma_Pkt* rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_free_pktq_);
int32_t status;
uint32_t qCount;
EnetQueue_initQ(&rxSubmitQ);
while((qCount > 0) && (rxPktInfo != nullptr))
{
EnetQueue_enq(&rxSubmitQ, &rxPktInfo->node);
rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_free_pktq_);
qCount--;
}
EnetAppUtils_validatePacketState(&rxSubmitQ,
EnetAppUtils_validatePacketState(p_packet_queue,
ENET_PKTSTATE_APP_WITH_FREEQ,
ENET_PKTSTATE_APP_WITH_DRIVER);
status = EnetDma_submitRxPktQ(dma_handle_, &rxSubmitQ);
status = EnetDma_submitRxPktQ(dma_handle_, p_packet_queue);
EnetAppUtils_assert(status == ENET_SOK);
qCount = EnetQueue_getQCount(&rxSubmitQ);
qCount = EnetQueue_getQCount(p_packet_queue);
/* Assert here, as during init, the number of DMA descriptors should be equal to
* the number of free Ethernet buffers available with app */
EnetAppUtils_assert(qCount == 0U);
@ -113,87 +108,64 @@ void free_rtos::EthRxFlow::submitFreeRxPkts(uint32_t qCount)
void free_rtos::EthRxFlow::rxProcessPktTask()
{
EnetDma_Pkt* rxPktInfo; /// <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EnetDma_PktQ rxReadyQ;
uint32_t readyQCount;
EnetDma_Pkt* rxPktInfo;
EnetDma_PktQ rxFreeQ;
int32_t status;
while(1)
{
if(enetDmaRxChId_ != ENET_DMA_RX_CH0) {
status = sem_[e_signalRxPkt].pend();
} else {
status = sem_[e_signalRxPkt].pend(semaphore_timeout_ticks_);
}
status = sem_[e_signalRxPkt].pend();
if(status != SystemP_SUCCESS) {
EnetAppUtils_print("RX Timeout ");
continue;
}
do {
EnetDma_PktQ rxFreeQ;
EnetQueue_initQ(&rxFreeQ);
rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_ready_pktq_);
EnetQueue_initQ(&rxFreeQ);
while(rxPktInfo != nullptr) {
//if (!passive_mode_) {
for (int j = 0 ; j < rxPktInfo->sgList.numScatterSegments; ++j)
{
eth_stack_.rx_handler(rxPktInfo->sgList.list[j].bufPtr, rxPktInfo->sgList.list[j].segmentFilledLen);
}
//}
status = EnetDma_retrieveRxPktQ(dma_handle_, &rxReadyQ);
EnetAppUtils_assert(status == ENET_SOK);
EnetDma_checkPktState( &rxPktInfo->pktState,
ENET_PKTSTATE_MODULE_APP,
ENET_PKTSTATE_APP_WITH_DRIVER,
ENET_PKTSTATE_APP_WITH_FREEQ);
readyQCount = EnetQueue_getQCount(&rxReadyQ);
EnetQueue_enq(&rxFreeQ, &rxPktInfo->node);
if(readyQCount == 0) {
break;
}
rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_ready_pktq_);
}
// Reload DMA with a new rx free queue as fast as possible
submitFreeRxPkts(readyQCount);
rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
while(rxPktInfo != nullptr) {
//if (!passive_mode_) {
for (int j = 0 ; j < rxPktInfo->sgList.numScatterSegments; ++j)
{
eth_stack_.rx_handler(rxPktInfo->sgList.list[j].bufPtr, rxPktInfo->sgList.list[j].segmentFilledLen);
}
//}
EnetQueue_enq(&rxFreeQ, &rxPktInfo->node);
rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
}
EnetAppUtils_validatePacketState(&rxFreeQ,
ENET_PKTSTATE_APP_WITH_DRIVER,
ENET_PKTSTATE_APP_WITH_FREEQ);
EnetQueue_append(&rx_free_pktq_, &rxFreeQ);
} while(readyQCount > 0);
submitFreeRxPktQ(&rxFreeQ);
}
}
bool free_rtos::EthRxFlow::open(uint32_t id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size)
bool free_rtos::EthRxFlow::open(TEthMacPorts port_id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size)
{
EnetApp_GetDmaHandleInArgs rxInArgs;
EnetApp_GetRxDmaHandleOutArgs rxChInfo;
constexpr uint32_t numPkts[2] = {ENET_DMA_RX_CH0_NUM_PKTS, ENET_DMA_RX_CH1_NUM_PKTS};
EnetAppUtils_print("rx_flow %u: opening flow...\r\n", id);
EnetAppUtils_print("rx_flow %u: opening flow...\r\n", port_id);
if (open_) {
EnetAppUtils_print("rx_flow %u: rx flow is already open. Do nothing.\r\n", id_);
EnetAppUtils_print("rx_flow %u: rx flow is already open. Do nothing.\r\n", port_id);
return true;
}
if (!rx_task.Create("rx_task", task_priority, rxTaskHandler, this, task_stack_size))
{
EnetAppUtils_print("rx_flow %u: failed to create rx task.\r\n", id_);
EnetAppUtils_print("rx_flow %u: failed to create rx task.\r\n", port_id);
return false;
}
id_ = id;
default_port_id_ = port_id;
enetDmaRxChId_ = enetDmaRxChId;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@ -219,23 +191,26 @@ bool free_rtos::EthRxFlow::open(uint32_t id, int32_t enetDmaRxChId, UBaseType_t
EnetAppUtils_assert(rxChInfo.useGlobalEvt == true);
EnetAppUtils_assert(rxChInfo.sizeThreshEn == 0U);
EnetAppUtils_assert(rxChInfo.maxNumRxPkts >= numPkts[enetDmaRxChId]);
EnetAppUtils_assert(rxChInfo.chIdx == id_);
EnetAppUtils_assert(rxChInfo.chIdx == port_id);
EnetAppUtils_assert(rxChInfo.useDefaultFlow == true);
if (dma_handle_ == nullptr)
{
EnetAppUtils_print("rx_flow %u: failed to open rx dma flow\r\n", id_);
EnetAppUtils_print("rx_flow %u: failed to open rx dma flow\r\n", port_id);
EnetAppUtils_assert(dma_handle_ != nullptr);
return false;
}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
initRxFreePktQ(this, &rx_free_pktq_, numPkts[enetDmaRxChId]);
submitFreeRxPkts(numPkts[enetDmaRxChId]/2);
EnetDma_PktQ rxFreeQ;
EnetQueue_initQ(&rxFreeQ);
initRxFreePktQ(this, &rxFreeQ, numPkts[enetDmaRxChId]);
submitFreeRxPktQ(&rxFreeQ);
open_ = true;
EnetAppUtils_print("rx_flow %u: rx flow open successfully\r\n", id);
EnetAppUtils_print("rx_flow %u: rx flow open successfully\r\n", port_id);
return true;
}

View File

@ -28,7 +28,7 @@ class EthRxFlow {
public:
EthRxFlow(TEthFrameMacAddr& mac_addr, EthStackIface& eth_stack);
bool open(uint32_t id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size);
bool open(TEthMacPorts port_id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size);
bool is_open() {return open_;}
@ -41,7 +41,8 @@ private:
friend void rxTaskHandler(void *appData); ///<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void initRxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue, uint32_t qCount);
void submitFreeRxPkts(uint32_t qCount);
void retrieveReadyRxPktQ();
void submitFreeRxPktQ(EnetDma_PktQ * p_packet_queue);
void rxProcessPktTask(); ///<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@ -51,9 +52,7 @@ private:
e_signalTotal
};
static constexpr uint32_t semaphore_timeout_ticks_ = 900;
uint32_t id_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TEthMacPorts default_port_id_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int32_t enetDmaRxChId_;
bool open_; /// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD> dma <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@ -68,7 +67,7 @@ private:
uint32_t rx_start_flow_idx_;
uint32_t rx_flow_idx_;
EnetDma_RxChHandle dma_handle_;
EnetDma_PktQ rx_free_pktq_;
EnetDma_PktQ rx_ready_pktq_;
bool passive_mode_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};

View File

@ -51,75 +51,51 @@ static void eth_initTxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue, ui
EnetQueue_getQCount(p_packet_queue));
}
static uint32_t eth_retrieveFreeTxPkts(EnetDma_TxChHandle * p_handle, EnetDma_PktQ * p_queque)
void free_rtos::txIsrHandler(void *appData)
{
EnetDma_PktQ txFreeQ;
EnetDma_Pkt *pktInfo;
uint32_t txFreeQCnt = 0U;
int32_t status;
EthTxFlow * tx_flow = (EthTxFlow *)appData;
EnetQueue_initQ(&txFreeQ);
/// <20><><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)
{
/// <20><><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);
while (NULL != pktInfo)
{
EnetDma_checkPktState(&pktInfo->pktState,
ENET_PKTSTATE_MODULE_APP,
ENET_PKTSTATE_APP_WITH_DRIVER,
ENET_PKTSTATE_APP_WITH_FREEQ);
/// <20><><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); /// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
}
}
else
{
EnetAppUtils_print("retrieveFreeTxPkts() failed to retrieve pkts: %d\r\n", status);
if(tx_flow == nullptr) {
return;
}
return txFreeQCnt; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tx_flow->retrieveFreeTxPktQ();
tx_flow->sem_[EthTxFlow::e_signalTxPkt].post();
}
free_rtos::EthTxFlow::EthTxFlow() :
id_{0},
default_port_id_{e_ethMac0},
open_{false},
tx_ch_num_{0}
{
EnetQueue_initQ(&tx_free_pktq_);
}
bool free_rtos::EthTxFlow::open(uint32_t id, int32_t enetDmaTxChId)
bool free_rtos::EthTxFlow::open(TEthMacPorts port_id, int32_t enetDmaTxChId)
{
if (id >= e_ethMacTotal) {
if (port_id >= e_ethMacTotal) {
return false;
}
EnetApp_GetDmaHandleInArgs txInArgs;
EnetApp_GetTxDmaHandleOutArgs txChInfo;
EnetAppUtils_print("tx_flow %u: opening flow...\r\n", id);
EnetAppUtils_print("tx_flow %u: opening flow...\r\n", port_id);
port_data_[id].tx_pkt_counter = 0;
port_data_[port_id].tx_pkt_counter = 0;
if (open_) {
EnetAppUtils_print("tx_flow %u: tx flow is already open. Do nothing.\r\n", id_);
EnetAppUtils_print("tx_flow %u: tx flow is already open. Do nothing.\r\n", port_id);
return true;
}
/* Open the TX channel */
txInArgs.notifyCb = nullptr;
txInArgs.cbArg = nullptr;
txInArgs.notifyCb = txIsrHandler;
txInArgs.cbArg = this;
EnetApp_getTxDmaHandle(enetDmaTxChId, &txInArgs, &txChInfo);
default_port_id_ = port_id;
tx_ch_num_ = txChInfo.txChNum;
dma_handle_ = txChInfo.hTxCh;
@ -128,7 +104,7 @@ bool free_rtos::EthTxFlow::open(uint32_t id, int32_t enetDmaTxChId)
if (dma_handle_ == nullptr)
{
EnetAppUtils_print("tx_flow %u: failed to open tx dma flow\r\n", id_);
EnetAppUtils_print("tx_flow %u: failed to open tx dma flow\r\n", port_id);
EnetAppUtils_assert(dma_handle_ != nullptr);
return false;
}
@ -137,7 +113,7 @@ bool free_rtos::EthTxFlow::open(uint32_t id, int32_t enetDmaTxChId)
open_= true;
EnetAppUtils_print("tx_flow %u: tx flow open successfully\r\n", id_);
EnetAppUtils_print("tx_flow %u: tx flow open successfully\r\n", port_id);
return true;
}
@ -158,6 +134,43 @@ void free_rtos::EthTxFlow::disable(TEthMacPorts port_id) {
port_data_[port_id].tx_enable = false;
}
void free_rtos::EthTxFlow::retrieveFreeTxPktQ()
{
EnetDma_PktQ txFreeQ;
EnetDma_Pkt *pktInfo;
int32_t status;
EnetQueue_initQ(&txFreeQ);
status = EnetDma_retrieveTxPktQ(dma_handle_, &txFreeQ);
if (status != ENET_SOK)
{
EnetAppUtils_print("retrieveFreeTxPktQ() failed to retrieve pkts: %d\r\n", status);
return;
}
EnetAppUtils_validatePacketState( &txFreeQ,
ENET_PKTSTATE_APP_WITH_DRIVER,
ENET_PKTSTATE_APP_WITH_FREEQ);
EnetQueue_append(&tx_free_pktq_, &txFreeQ);
}
EnetDma_Pkt* free_rtos::EthTxFlow::getTxPktInfo()
{
EnetDma_Pkt *txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
while(txPktInfo == NULL)
{
sem_[EthTxFlow::e_signalTxPkt].pend();
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
}
return txPktInfo;
}
bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t len)
{
if (port_id >= e_ethMacTotal) {
@ -176,65 +189,57 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t
EnetQueue_initQ(&txSubmitQ);
eth_retrieveFreeTxPkts(&dma_handle_, &tx_free_pktq_);
txPktInfo = getTxPktInfo();
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
while(txPktInfo == NULL)
if (txPktInfo == NULL)
{
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
}
EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", port_id);
if (txPktInfo != NULL)
{
///<2F><><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;
txPktInfo->sgList.numScatterSegments = 1;
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);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> txPktInfo <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> txSubmitQ
EnetQueue_enq(&txSubmitQ, &txPktInfo->node);
}
else
{
EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", id_);
return false;
}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DMA
memcpy(txPktInfo->sgList.list[0].bufPtr, p_data, len);
txPktInfo->sgList.list[0].segmentFilledLen = len;
txPktInfo->sgList.numScatterSegments = 1;
txPktInfo->chkSumInfo = 0U;
txPktInfo->appPriv = nullptr;
txPktInfo->tsInfo.txPktSeqId = 0;
txPktInfo->txPktTc = 0; /// Traffic class 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);
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);
EnetAppUtils_print("tx_flow %u: Failed to submit TX pkt queue: %d\r\n", port_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>
++port_data_[port_id].tx_pkt_counter;
return true;
}
bool free_rtos::EthTxFlow::send(TxFlowHandlerArgs& handlerArgs, uint32_t numScatterSegments)
{
if (handlerArgs.port_id >= e_ethMacTotal) {
TEthMacPorts port_id = handlerArgs.port_id;
if (port_id >= e_ethMacTotal) {
EnetAppUtils_print("Wrong port id\r\n");
return false;
}
if (port_data_[handlerArgs.port_id].tx_enable == false) {
if (port_data_[port_id].tx_enable == false) {
return false;
}
@ -244,52 +249,45 @@ bool free_rtos::EthTxFlow::send(TxFlowHandlerArgs& handlerArgs, uint32_t numScat
EnetQueue_initQ(&txSubmitQ);
eth_retrieveFreeTxPkts(&dma_handle_, &tx_free_pktq_);
txPktInfo = getTxPktInfo();
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
while(txPktInfo == NULL)
if (txPktInfo == NULL)
{
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_);
}
EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", port_id);
if (txPktInfo != NULL)
{
for(size_t scatter_segment = 0; scatter_segment < numScatterSegments; 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.numScatterSegments = numScatterSegments;
txPktInfo->chkSumInfo = 0U;
txPktInfo->appPriv = nullptr;
txPktInfo->tsInfo.txPktSeqId = 0;
txPktInfo->txPktTc = 0; /// Traffic class IPv6
txPktInfo->tsInfo.enableHostTxTs = false;
txPktInfo->txPortNum = (Enet_MacPort)handlerArgs.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;
}
for(size_t scatter_segment = 0; scatter_segment < numScatterSegments; 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.numScatterSegments = numScatterSegments;
txPktInfo->chkSumInfo = 0U;
txPktInfo->appPriv = nullptr;
txPktInfo->tsInfo.txPktSeqId = 0;
txPktInfo->txPktTc = 0; /// Traffic class 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);
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);
EnetAppUtils_print("tx_flow %u: Failed to submit TX pkt queue: %d\r\n", port_id, status);
return false;
}
++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>
++port_data_[handlerArgs.port_id].tx_pkt_counter;
return true;
}

View File

@ -13,6 +13,7 @@
#include "free_rtos/ethernet/eth_tx_flow_iface.hpp"
#include "free_rtos/handler_store/handler_store.hpp"
#include "free_rtos/semaphore/semaphore.hpp"
namespace free_rtos {
@ -20,7 +21,7 @@ class EthTxFlow : public EthTxFlowIface {
public:
EthTxFlow();
bool open(uint32_t id, int32_t enetDmaTxChId);
bool open(TEthMacPorts port_id, int32_t enetDmaTxChId);
bool is_open() {return open_;}
@ -31,20 +32,32 @@ public:
virtual bool send(TEthMacPorts port_id, uint8_t * p_data, uint32_t len) override;
virtual bool send(TxFlowHandlerArgs& handlerArgs, uint32_t numScatterSegments) override;
private:
friend void txIsrHandler(void *appData);
enum SignalsId {
e_signalTxPkt,
e_signalTotal
};
struct PortData {
bool tx_enable;
uint32_t tx_pkt_counter;
};
uint32_t id_;
TEthMacPorts default_port_id_;
bool open_;
Semaphore sem_[e_signalTotal];
//-------------------------------------------------
uint32_t tx_ch_num_;
EnetDma_TxChHandle dma_handle_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> DMA
EnetDma_PktQ tx_free_pktq_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
PortData port_data_[e_ethMacTotal];
void retrieveFreeTxPktQ();
EnetDma_Pkt* getTxPktInfo();
};