工具/软件:
尊敬的先生:
我们 使用快速启动 CPSW 示例评估 CPSW 发送函数、我的发送函数如下所示:
while(1)
{
EnetQueue_initQ(&txSubmitQ);
EnetApp_retrieveFreeTxPkts();
/* Dequeue one free TX Eth packet */
txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&gEnetApp.txFreePktInfoQ);
if (txPktInfo != NULL)
{
/* Fill the TX Eth frame with test content */
txFrame = (EthFrame *)txPktInfo->sgList.list[0].bufPtr;
memcpy(txFrame->hdr.dstMac, &dstMac[0], ENET_MAC_ADDR_LEN);
memcpy(txFrame->hdr.srcMac, &srcMac[0U], ENET_MAC_ADDR_LEN);
txFrame->hdr.etherType = 0x88a4;
txPktInfo->sgList.list[0].segmentFilledLen = 120;
memcpy(&txFrame->payload[0U],
&layload[0U],
txPktInfo->sgList.list[0].segmentFilledLen - sizeof(EthFrameHeader));
txPktInfo->sgList.numScatterSegments = 1;
txPktInfo->chkSumInfo = 0U;
txPktInfo->appPriv = &gEnetApp;
txPktInfo->tsInfo.enableHostTxTs = false;
EnetDma_checkPktState(&txPktInfo->pktState,
ENET_PKTSTATE_MODULE_APP,
ENET_PKTSTATE_APP_WITH_FREEQ,
ENET_PKTSTATE_APP_WITH_DRIVER);
// EnetAppUtils_print("before enqueue txPkt %d \r\n", i);
/* Enqueue the packet for later transmission */
EnetQueue_enq(&txSubmitQ, &txPktInfo->node);
}
else
{
EnetAppUtils_print("Drop due to TX pkt not available\r\n");
}
// EnetAppUtils_print("before Transmit %d \r\n", i);
/* Transmit all enqueued packets */
status = EnetDma_submitTxPktQ(gEnetApp.hTxCh, &txSubmitQ);
if (status != ENET_SOK)
{
EnetAppUtils_print("Failed to submit TX pkt queue: %d\r\n", status);
}
i++;
// EnetAppUtils_print("before sleep %d \r\n", i);
// ClockP_usleep(200000U);
}
但发送 230 个软件包后、该函数将冻结、不再发送软件包、通过查看 JTAG、我发现该函数冻结在 enet_uDMa.c 文件中的 EnetDma_submitTxPktQ -> EnetUdmaStats_addCnt、如下所示:
int32_t EnetDma_submitTxPktQ(EnetDma_TxChHandle hTxCh,
EnetDma_PktQ *pSubmitQ)
{
EnetPer_Handle hPer = hTxCh->hDma->hPer;
int32_t retVal = UDMA_SOK;
Udma_RingHandle ringHandle;
#if ENET_CFG_IS_ON(DEV_ERROR)
if ((NULL == hTxCh) ||
(NULL == pSubmitQ))
{
ENETTRACE_ERR_IF((NULL == hTxCh), "[Enet UDMA] hTxCh is NULL!!\n");
ENETTRACE_ERR_IF((NULL == pSubmitQ), "[Enet UDMA] pSubmitQ is NULL!!\n");
Enet_assert(FALSE);
retVal = UDMA_EBADARGS;
}
else
#endif
{
#if defined(ENETDMA_INSTRUMENTATION_ENABLED)
uint32_t startTime, diffTime;
uint32_t pktCnt, notifyCount;
startTime = EnetOsal_timerRead();
pktCnt = EnetQueue_getQCount(pSubmitQ);
#endif
#if (UDMA_SOC_CFG_UDMAP_PRESENT == 1)
ringHandle = hTxCh->fqRing;
#else
ringHandle = hTxCh->cqRing;
#endif
/* Enqueue descs to fqRing regardless of caller's queue state */
if (EnetQueue_getQCount(pSubmitQ) > 0U)
{
retVal = EnetUdma_submitPkts(hPer,
ringHandle,
pSubmitQ,
hTxCh->hDmaDescPool,
hTxCh->txChPrms.disableCacheOpsFlag,
ENET_UDMA_DIR_TX
#if (UDMA_SOC_CFG_PROXY_PRESENT == 1)
,
hTxCh->hUdmaProxy
#endif
);
}
/* If fqRing ran out of space it is not an error, packets will be re-submitted by application*/
if (UDMA_ETIMEOUT == retVal)
{
ENETTRACE_INFO("TX Channel FQ underflow had occurred\n");
retVal = UDMA_SOK;
}
#if defined(ENETDMA_INSTRUMENTATION_ENABLED)
EnetUdmaStats_addCnt(&hTxCh->stats.txSubmitPktOverFlowCnt, EnetQueue_getQCount(pSubmitQ));
pktCnt -= EnetQueue_getQCount(pSubmitQ);
EnetUdmaStats_addCnt(&hTxCh->stats.txSubmitPktEnq, pktCnt);
diffTime = EnetOsal_timerGetDiff(startTime);
notifyCount = hTxCh->stats.submitPktStats.dataNotifyCnt & (ENET_DMA_STATS_HISTORY_CNT - 1U);
hTxCh->stats.submitPktStats.readyDmaDescQCnt[notifyCount] = hTxCh->hDmaDescPool->count;
EnetUdmaStats_updateNotifyStats(&hTxCh->stats.submitPktStats, pktCnt, diffTime);
#endif
}
顺便说一下、Marco ENETDMA_Instrumentation_enabled 对于 CPSW DMA 发送的正常功能是否必不可少? 我可以在哪里关闭它?我可以在哪里关闭它?
谢谢!