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