What are the stack and heap set in the GCC linker script used for?

Hi

In the linker script for GCC the following are set:

ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(DTC_STACK) + LENGTH(DTC_STACK); /* end of "RAM" Ram type memory */

_Min_Heap_Size  = 4K; /* required amount of heap */
_Min_Stack_Size = 4K; /* required amount of stack */

/* Memories definition */
MEMORY
{
  DTC_STACK    	(xrw)    : ORIGIN = 0x10000000,   LENGTH = _Min_Heap_Size + _Min_Stack_Size
  DTCM_MISC    	(xrw)    : ORIGIN = 0x10000000 + _Min_Heap_Size + _Min_Stack_Size,  LENGTH = 10K - _Min_Heap_Size + _Min_Stack_Size
  RAM     		(xrw)    : ORIGIN = 0x20000000,   LENGTH = 32K - 1k
  RAM_NVS		(xrw)    : ORIGIN = 0x20008000,   LENGTH = 1K
  FLASH    		 (rx)    : ORIGIN = 0x8000000,    LENGTH = 128K
}

I am guessing the stack is used for interrupt processing, saving registers etc, but what is the heap used for. What’s the best way of working out the size necessary for each of these?

Thanks
Rob

The heap size defined in the linker file will generally be for the standard C library malloc function, which is likely not thread-safe unless you have taken the steps to make it so. (or the environment has been specially created for FreeRTOS and has taken the steps by default to make it safe).

As to figuring out how much space you need, you really need to know your application and its needs, or start big and see what is left after testing.

So if I am not using dynamic memory in my startup functions and for my tasks can this be set to 0?

If you are sure that you application does not use malloc (directly or indirectly), then yes, you can set it to 0.

To be on the safe side, you may want to consult with your project map file to find out what _Min_Heap_Size resolves to and what identifiers are located in that range. Some eco systems and/or HALs employ non standard and sometimes subtle deviations for their own startup code.

Hi All

I did a bit of research and found that stdio - printf when used to print variables uses the heap. If printf just prints fixed text with no variables it does not use the heap. So the size of the heap must be determined by the number of variables to be printed within any printf function. So your most complex printf function determines minimum heap size if no other dynamic memory is used. If your program doesn’t use dynamic memory and you don’t printf variables the heap can be set to zero.

printf("Fred")             => no heap
printf("Fred %0d, fredvar) => heap used

I’m glad we sorted that out!

Regards
Rob

Additional:

The stdio lib that I’m using is the stdio.h 5.3 (Berkeley) 3/15/86. I downloaded the source code at:
Berkey c library

And sure enough malloc is used in the vFprintf.c and vfwprintf.c

Thank you for sharing your solution. As @richard-damon has already mentioned, if you are calling printf from multiple threads (and therefore, malloc from multiple threads) make sure either it is thread-safe or you have taken the steps required by your C library to make it thread-safe.

printf (stdio.h 5.3 (Berkeley) isn’t thread safe, but I am only using it one task at a time so I haven’t had any problems. Would a mutex be a safe way of using this printf to avoid re-entry issues? If so I would like to test this for future use.

Another option which is thread safe is:

  • @author (c) Eyal Rozenberg eyalroz1@gmx.com
  •         2021-2022, Haifa, Palestine/Israel
    
  • @author (c) Marco Paland (info@paland.com)
  •         2014-2019, PALANDesign Hannover, Germany
    

The implementations are thread-safe; re-entrant; use no functions from
the standard library; and do not dynamically allocate any memory.

printf_Rozenberg which is thread safe and optimised for embedded systems. I have used this successfully in the past.

You can get it here:

Fast thread safe printf

Regards
Rob

Yes, it would be.

Thank you for sharing!