FreeRTOS TCP/IP pdFREERTOS_ERRNO_ENOMEM (Nucleo-F767Zi)

Hi,
I’m currently working on getting the FreeRTOS TCP/IP stack running on the Nucleo-F767Zi. The goal is to communicate with my PC over an ethernet cable. It is currently running so far that I can connect successfully with my Pc. If I want to send or receive a message I get the error code pdFREERTOS_ERRNO_ENOMEM back from the commands FreeRTOS_recv and FreeRTOS_send. Even if I want to send or receive a simple 1. I’m a bit at a loss as to how to fix this error. In the API References there is the following sentence : If there was not enough memory for the socket to be able to create either an Rx or Tx stream then -pdFREERTOS_ERRNO_ENOMEM is returned.
But unfortunately I can’t do anything with it. What does this error tell me and how can I fix it.
I set the StackDepth to 400, ipconfigTCP_MSS is set to 1460 and ipconfigNETWORK_MTU to 1526. For further information I use the BufferAllocation_2 as advised and in the FreeRTOSConfig.h I set
#define configSUPPORT_DYNAMIC_ALLOCATION to 1.

Where is pdFREERTOS_ERRNO_ENOMEM getting set? If I look in FreeRTOS_send() I see it calls prvTCPSendCheck(), and inside prvTCPSendCheck() pdFREERTOS_ERRNO_ENOMEM gets set if either “pxSocket->u.xTCP.bits.bMallocError != pdFALSE_UNSIGNED” or “pxSocket->u.xTCP.txStream == NULL”. That would seem to be indicative of a malloc() failure.

Which heap allocation scheme are you using? What is configTOTAL_HEAP_SIZE set to? Do you have a malloc failed hook defined?

Thank you for responding so quickly.
pdFREERTOS_ERRNO_ENOMEM is set at send and receive with the if condition pxSocket->u.xTCP.bits.bMallocError != pdFALSE_UNSIGNED.
I use the heap_4 allocation scheme and my whole heap is set as
#define configTOTAL_HEAP_SIZE ((size_t)15360)
I have not defined the malloc failed hook.

Recommend you do define this as it would give you quick insight to where you issue was as as far as I can see bMallocError can only get set here https://github.com/FreeRTOS/FreeRTOS/blob/V10.3.1/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c#L2958 which would have triggered the malloc failed hook.

So you have run out of heap, which means you either need to tune your system, including the TCP stack, to use less memory or you need to increase the heap site.

1 Like

Here is a short overview of the usage of RAM in a mid-size MCU:

ipconfig item Value
NETWORK_MTU 1500
TCP_MSS 1460
USE_TCP 1
USE_TCP_WIN 1
TCP_RX_BUFFER_LENGTH 2920
TCP_TX_BUFFER_LENGTH 2920
USE_DHCP 0
RAM that is always allocated (statically or on the heap):
ipconfig item Value PerUnit Total
NUM_NETWORK_BUFFER_DESCRIPTORS 8 1572 12576
TCP_WIN_SEG_COUNT 32 64 2048
EVENT_QUEUE_LENGTH 25 8 200
IP_TASK_STACK_SIZE_WORDS 512 4 2048
ARP_CACHE_ENTRIES 6 12 72
DNS_CACHE_ENTRIES 4 28 112
Total 17056

In the first column you see the ipconfig item, like e.g. ipconfigNETWORK_MTU.

Beside the above, malloc will be used to allocate sockets and their TCP stream buffers.
The length of the stream buffers depends on ipconfigTCP_RX_BUFFER_LENGTH and ipconfigTCP_TX_BUFFER_LENGTH, unless overridden by the socket options FREERTOS_SO_RCVBUF and FREERTOS_SO_SNDBUF.

Object Size
UDP-Socket 100
TCP-Socket 432
TX-Buffer 2920
RX-Buffer 2920

When a TCP socket is only used in one direction, it will only create a single stream buffer.
Note that BufferAllocation_1.c is used, which means that all network buffers are allocated statically (8 x1572 bytes).

1 Like

Many thanks for the listing. Since I have only used the LwIP STACK to establish ethernet connections and the standard heap size of :
#define configTOTAL_HEAP_SIZE ((size_t)15360)
for this always sufficed, I did not think that the heap size could be too small.
But because of its listing I soon realized that I had to increase my TOTAL_HEAP_SIZE.
Thanks for the fast and helpful tips.

The utility that created the above table is now available in a PR #1828

Beside increasing configTOTAL_HEAP_SIZE you can also decrease the memory usage, especially with these macros:

NUM_NETWORK_BUFFER_DESCRIPTORS
TCP_RX_BUFFER_LENGTH
TCP_TX_BUFFER_LENGTH
TCP_WIN_SEG_COUNT
NETWORK_MTU

They are all described on FreeRTOS.org

1 Like