cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Base Heap and Stack Settings - Handy Hints #2

Garnett.Robert
Senior III

Hi,

In most of my projects I use the CCM memory for the stack and heap and as it is limited, the question arises how much should I allocate. I specify the stack and heap in the linker script: When using FreeRTOS teach task maintains its own stack, however the base stack set in the linker script is used for interrupt register stacking and the passing of function variables before the scheduler is started. So a stack of non zero size is always required unless there are no interrupts and no function calls.

 

/* Entry Point */ 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 = 256; /* required amount of heap */ _Min_Stack_Size = 1K; /* 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 - 10 FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K }

 

I occurred to me that if I am not using dynamic memory (heaps) and in the case of FreeRTOS using static allocation of operating system objects like tasks and sem's, I should be able to set the heap to zero.  However when using standard c functions like those from string.c and stdio.c some of these require a heap. For example a printf function that only prints a literal string with no variables with (no formatting), the heap is NOT used. If you format variables within the printf function then the heap IS used viz:

printf("Fred") /* => No Heap */ printf(Fres = %0d, fred) /* => Heap is used */

If you don't allocate a heap when using printf with formatting a crash will probably occur.  ST Uses the stdio.h 5.3 (Berkeley) 3/15/86 library.  A list of all of the modules that use malloc in at least one of their functions is attached.  There are a lot!

To work out what a program requires, fill the stack and heap with an "0xA5" pattern by:

int main(void) { /* Initialise DTCM_STACK */ #define DTCM_STACK_START ((void *)0x10000000) memset((void*)DTCM_STACK_START, 0xA5, 1280);

 

Run the application and use the memory browser to examine the heap and stack to see how many of the A5 patterns were overwritten.  Of course you must ensure all of the code is covered so that all possible heap and stack uses occur.

 

Snag_1a8bc2d8.png

In my case I started off allocating 2k for the heap and 2k for the stack. After checking the usage I found I only used 64 bytes of heap and 336 bytes of stack.  I set my heap to 256 and the stack to 1024 (1k) which saved me nearly 3k of ccm.  I could have gone smaller, but it was a relatively small project and ram wasn't at a premium.

So the trick is to start with some conservative, larger values for the heap and stack and then if you are running out of ram or you want to pack more globals into the ccm for a bit of extra speed examine the stack and heap and adjust accordingly.

If you want to look at the Berkley c lib's thay can be downloaded here:

 

https://chromium.googlesource.com/native_client/nacl-newlib/+/0670637d40139fb01b67beb7fa41846e8dd0ca27 

Hope this useful

 

 

 

 

 

 

0 REPLIES 0