Problem with heap_4 in FreeRTOS-TCP

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:

  pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( xBytesReceived, 0);

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:

  pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );

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.

Can someone help me with this one?

Is this the assert you get stuck in?

Do you handle cases where you run out of heap space? Do you have a malloc failed hook defined?

Is this the assert you get stuck in? _ttps://

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
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)

Can you try increasing the heap size? The heap size is controlled using configTOTAL_HEAP_SIZE macro in your FreeRTOSConfig.h file.

I’ll definitely try that tomorrow, but it’s already 2/3 of MCU RAM.

#define configMINIMAL_STACK_SIZE ( ( uint16_t ) 256 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 20 * 1024 ) )

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 )
					u8_LAN9352_recieveBuf(MDR_SSP1, RX_FIFO, pxBufferDescriptor->pucEthernetBuffer, xBytesReceived);
					u8_LAN9352_recieveBuf(MDR_SSP1, RX_FIFO, FSC, sizeof(FSC));
					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
						iptraceNETWORK_INTERFACE_RECEIVE(); /// log receive success

And second is NetworkInterface.c

BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer,
                                    BaseType_t xReleaseAfterSend )
	uint32_t command_a, command_b = 0;
	command_a = COM_A_FIST | COM_A_LAST | (pxNetworkBuffer->xDataLength);
	command_b = 0xAAAA0000 | (pxNetworkBuffer->xDataLength);

	u8_LAN9352_writeEthFrame(MDR_SSP1, command_a, command_b, 0, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength);
    if( xReleaseAfterSend != pdFALSE )
	return pdTRUE;

Have you checked for stack overflows?

I use
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.

Well, seems it has smth to do with

#define ipconfigETHERNET_MINIMUM_PACKET_BYTES    ( 200 )

When I removed this config parameter everyting now works nicely.