How should I use Cortex-M heap and stack ?

Questions:

  • How does the heap and stack work with Cortex-M devices, GCC and the default files provided by Ride7?
  • What are the addresses and sizes of heap and stack and how do I change them?
  • How do I know if the heap or stack is full?

Answers:

The Heap top is initialized at the end of the RAM used for variables (.data, .bss), and the heap grows up (increasing addresses). Heap top init is done by the first call to _sbrk. (see below).

The Stack Pointer is initialized at the end of the RAM, and the stack grows down (decreasing addresses). Stack Pointer init is done by the startup.

These values are defined by the linker scripts ("end" for the heap top and "_estack" for Stack Pointer).

There is no fixed limit for stack or heap.

  • The _sbrk function is called by malloc when it needs to increase the size of the heap.
  • The _sbrk function checks if there is heap/stack collision. The self-explanatory source code of _sbrk is here: [Ride]\Lib\ARM\std_sbrk\sbrk.c
    You can copy this file into your working directory and include it in your project, then look at the source to understand how a collision is detected.
    Then you can add your custom treatment (reset, toggle LED, message to UART, ...) instead of the default infinite loop, or simply add a breakpoint to see it in the debugger.
    You can also change or completely rewrite the _sbrk function if you wish. For example if you want to fix a hard limit for the heap size.

Of course you should also take a look at the linker scripts and startup.

This usually needs to be completely reworked when you use an OS (several stacks...). Your OS provider should have done it for you (the way to do it depends on the OS).

The "minimum_stack_size" and "._usrstack" declared in our default linker script are just a virtual check to ensure that after allocating RAM for data and bss there still is enough room for the stack _and_ the heap.
In fact they should be called "minimum_stack_plus_heap_size" and "._stack_and_heap_check".
Also, its address is NOT the location of the stack. You can increase it easily by either changing it in your linker script (if you have a custom linker script) or directly in the linker/scripts and linker/more options (if you use the custom linker script).
If you define custom sections that are allocated in RAM, take care to either place them before bss, or to change the definition of "end" accordingly.