Hello,
I’m trying to use TCP stack on ARM Cortex-M3 based MCU (MAC driver is a separate SPI chip) and recently I have accounted a problem.
Application is running some time after starting FreeRTOS_IPInit(). It recieves packets and even can transmit them (at least application manage to send ARP announcment). But then it’s getting infinite loop inside this function:
I read forum looking for similar problems and found that I can use “configASSERT( x )” to to find where a problem can be.
So this lead me to file’s “heap_4.c” function “void * pvPortMalloc( size_t xWantedSize )”, line 206:
Clearly I got some problem with memory managment, but there’s no tasks using memory allocation, exept FreeRTOS-TCP kernel and one I created to recieve frames.
Is this the assert you get stuck in? _ttps://github.com/FreeRTOS/FreeRTOS-Kernel/blob/V10.4.6/portable/MemMang/heap_4.c#L207
Yes, that’s right.
Malloc failed hook defined but with assert enabled application never reach it.
If I disable assert then application fall into infinite loop here
_ttps://github.com/FreeRTOS/FreeRTOS-Kernel/blob/V10.4.6/portable/MemMang/heap_4.c#L399
Or sometimes in Malloc failed hook.
P.S. there’s almost no tasks in my application now, and surelly enough memory to hold more frames, I can see it in debbuger.
P.P.S. Sorry for links, new user)
I heard this can happen due to data corruption.
There’re two places where dynamic allocation used
First is ethernet buff receive routine (don’t look that it’s not a deferred interrupt and not dma, I just want make it work first)
void ethRxThread(void *arg)
{
NetworkBufferDescriptor_t *pxBufferDescriptor = NULL;
size_t xBytesReceived = 0;
IPStackEvent_t xRxEvent;
uint8_t FSC[4] = {0};
uint8_t packet_cnt = 0;
for( ;; )
{
packet_cnt = (u32_LAN9352_readReg(MDR_SSP1, RX_FIFO_INF) & 0x00FF0000) >> 16; // See how many Ethernet frames were received
if((packet_cnt > 0) && (packet_cnt < 0xFF))
{
for(uint8_t i = 0; i < packet_cnt; i++)
{
xBytesReceived = ((u32_LAN9352_readReg(MDR_SSP1, RX_STATUS_FIFO) & 0x3FFF0000) >> 16) - 4; // See how much data a single frame contain (minus FSC)
pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( xBytesReceived, pdMS_TO_TICKS(0) ); // Allocate a network buffer descriptor
if( pxBufferDescriptor != NULL )
{
portENTER_CRITICAL();
u8_LAN9352_recieveBuf(MDR_SSP1, RX_FIFO, pxBufferDescriptor->pucEthernetBuffer, xBytesReceived);
u8_LAN9352_recieveBuf(MDR_SSP1, RX_FIFO, FSC, sizeof(FSC));
portEXIT_CRITICAL();
pxBufferDescriptor->xDataLength = xBytesReceived;
xRxEvent.eEventType = eNetworkRxEvent;
xRxEvent.pvData = (void *) pxBufferDescriptor; /// put pointer to the received data in the event
/// send the event to the TCP/IP stack
if (xSendEventStructToIPTask(&xRxEvent, 0) == pdFALSE)
{
/// error, buff couldn't be sent to the IP task, release it and log
vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor);
iptraceETHERNET_RX_EVENT_LOST();
}
else
{
iptraceNETWORK_INTERFACE_RECEIVE(); /// log receive success
}
}
else
{
iptraceETHERNET_RX_EVENT_LOST();
}
}
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
I use #define configCHECK_FOR_STACK_OVERFLOW 1
But application almost never fall into it.
I checked pxCurrentTask structure for “ethRxThread” when it got stacked
Stack is almoust empty.
In Memory debug I can see that application has free space left for frames when it fall into infinite loop. In fact in almost every run it uses only one buffer at 0x20002532. Very rare it happens to use two or three buffers.
I guess smth derails memory allocation function at some point.