cancel
Showing results for 
Search instead for 
Did you mean: 

Not enough memory to do an TCP alloc

Jvan .10
Associate III

The first step succeed and I'm able to ping my Nucleo H745ZI-Q.

Next step would be creating a TCP connection, this doesn't work because of some memory related problems.

Calling echoclient_pcb = tcp_new() gives me back a NULL.

/**
 * @ingroup tcp_raw
 * Creates a new TCP protocol control block but doesn't place it on
 * any of the TCP PCB lists.
 * The pcb is not put on any list until binding using tcp_bind().
 * If memory is not available for creating the new pcb, NULL is returned.
 *
 * @internal: Maybe there should be a idle TCP PCB list where these
 * PCBs are put on. Port reservation using tcp_bind() is implemented but
 * allocated pcbs that are not bound can't be killed automatically if wanting
 * to allocate a pcb with higher prio (@see tcp_kill_prio())
 *
 * @return a new tcp_pcb that initially is in state CLOSED
 */
struct tcp_pcb *
tcp_new(void)
{
  return tcp_alloc(TCP_PRIO_NORMAL);
}

As we can read on line 6, it's cause is unavailable memory.

Does anyone know where this memory issue is caused? I added my MPU config and FLASH/RAM configs.

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};
 
  /* Disables the MPU */
  HAL_MPU_Disable();
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x30040000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x30044000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
 
}

Thanks!

7 REPLIES 7
TDK
Guru

Try increasing the size of your heap.

If you feel a post has answered your question, please click "Accept as Solution".

You have to provide the functionality of tcp_alloc(), find in the source files where this is implemented. Likely uses malloc() of the regular heap.

You might need to look at how your tools are allocating (GNU _srbk), and from where. You might need to create your own allocator from a different pool to meet specific needs/requirements.

The pool obviously needs to be big enough to hold all your demands, and you should perhaps check what those are, and make sure they are released once used so you don't leak resources.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

_Min_Heap_Size = 0x200 ; /* required amount of heap */

Increase heap size to? 250? 300? higher?

0x200 is quite small. I would set it to 0x2000 if you have the space, but I don't know the other memory requirements of your program.
If you feel a post has answered your question, please click "Accept as Solution".
Osto
Senior

I have also the opinion as Tesla.

Check syscall.c or sysmem.c (depends on your MCU) in Core/src directory and theck the funtionality. Every time malloc need a new area, it calls __sbrk and ask for the amount of memory. The __sbrk extends the memory until end of heap (same as bottom of stack). (You need also to check the linker script to undestand it. Give him what he want and you will get result. Take care that a TCP package can be up to ~12K (Jumbo frames). If you want to crash, you need to take care about it.

Piranha
Chief II

Guys, by default lwIP doesn't use malloc()/free(). It can be configured to do it, but it is not recommended. lwIP has it's own pool implementation and it creates a bunch of pools for specific purposes.

https://lwip.fandom.com/wiki/Lwipopts.h#Memory_management_.28RAM_usage.29

Also jumbo frames are not supported in ST's code at lwIP driver level. And regardless of the support, the DMA will never write past the buffers it has been given. When necessary, it splits the frame over multiple buffers and, when there are no free buffers, it just enters the suspended state.

@Community member​ , @Osto​ 

This was only a warning. I had a project from a friend who didnt care about jumbo frames and he needed more than 2 months to find the problem. A lot of things could cause the problem when Jumbo frames are received. I had also a open source project with an ESP32 which had exactly the same problem. Also take care.