Part Number: TM4C129ENCPDT
I was having issues when running LWIP portfor TIRTOS where the pBuf would run out , it took some tracking down but I found the issue in the Ethernet driver port.
There is a bug in the LWIP port example for TM4C129ENCPDT
"C:\ti\TivaWare_C_Series-2.2.0.295\third_party\lwip-1.4.1\ports\tiva-tm4c129\netif\tiva-tm4c129.c"
The bug is in the "tivaif_receive" function and occurs when the last descriptor list contains part of an incomplete frame.
If the following check fails for the last descriptor to be processed (DES0_RX_STAT_LAST_DESC is not set)
if (pDescList->pDescriptors[pDescList->ui32Read].Desc.ui32CtrlStatus &
DES0_RX_STAT_LAST_DESC)
The code automatically allocates a new pBuff to this descriptor (even though the current one hasn't been handled).
My work around was to have the function check if the last pBuf was handled before allocating a new on to the descriptor.
// Find the next descriptor in the chain, taking care to wrap.
ui32NextDescriptor = pDescList->ui32Read + 1;
if (ui32NextDescriptor == pDescList->ui32NumDescs)
{
ui32NextDescriptor = 0;
}
// We didn't finish with the last buffer, frame wasn't complete
if (pBuf && (ui32NextDescriptor == ui32DescEnd))
{
// Let DMA get the data next time
DRIVER_STATS_DEC(RXBufReadCount);
break;
}
else
{
// Allocate a new buffer for this descriptor
pDescList->pDescriptors[pDescList->ui32Read].pBuf = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
pDescList->pDescriptors[pDescList->ui32Read].Desc.ui32Count = DES1_RX_CTRL_CHAINED;
if (pDescList->pDescriptors[pDescList->ui32Read].pBuf)
{
// We got a buffer so fill in the payload pointer and size.
pDescList->pDescriptors[pDescList->ui32Read].Desc.pvBuffer1 = pDescList->pDescriptors[pDescList->ui32Read].pBuf->payload;
pDescList->pDescriptors[pDescList->ui32Read].Desc.ui32Count |= (pDescList->pDescriptors[pDescList->ui32Read].pBuf->len <<
DES1_RX_CTRL_BUFF1_SIZE_S);
// Give this descriptor back to the hardware
pDescList->pDescriptors[pDescList->ui32Read].Desc.ui32CtrlStatus = DES0_RX_CTRL_OWN;
}
else
{
LWIP_DEBUGF(NETIF_DEBUG, ("tivaif_receive: pbuf_alloc error\n"));
pDescList->pDescriptors[pDescList->ui32Read].Desc.pvBuffer1 = 0;
// Update the stats to show we couldn't allocate a pbuf.
DRIVER_STATS_INC(RXNoBufCount);
LINK_STATS_INC(link.memerr);
// Stop parsing here since we can't leave a broken descriptor in the chain.
break;
}
// Move on to the next descriptor in the chain, taking care to wrap.
pDescList->ui32Read = ui32NextDescriptor;
}
This works well for me, with no more lost pBuf, but may not be the ideal way, would value feedback.