Search code examples
embeddedcortex-m

Cortex M0+ Bootloader Passing Top Address in RAM to App For Stack Pointer Address - Correct?


I have a Cortex M0+ device I have developed a bootloader and application for, partially based on some sample code from the IC manufacturer. In the bootloader, just before jumping to the app, the bootloader retrieves an address for the stack pointer and the reset vector of the app. I have verified using the map file of the app that the address is correct. However, the stack pointer address it gets is the topmost address in RAM (0x20008000 in this case). My understanding is the Cortex stack (at least for the "lower" devices like the M0) grows down. I just wanted to confirm that this is the address one should expect to be used for the stack pointer in this scenario.


Solution

  • This isn't a feature of the particular Cortex CPU. All ARM CPUs (including Cortex) support both ascending and descending stacks, as well as "full" and "empty" stacks.

    An "ascending" stack grows up from low memory addresses to higher memory addresses. Conversely, a "descending" stack grows from high memory addresses, down to lower addresses.

    A "full" stack is one where the stack pointer points to a memory location that contains data, and the stack pointer needs to be modified (incremented or decremented) before storing the next value.

    An "empty" stack is where the stack pointer is already pointing at the next free space. To push data, you store it at the current stack pointer, then modify the stack pointer.

    This is all described here, and includes this:

    The Procedure Call Standard for the ARM Architecture (AAPCS), and the ARM and Thumb C and C++ compilers always use a full descending stack. The PUSH and POP instructions assume a full descending stack. They are the preferred synonyms for STMDB and LDM with writeback.

    So having the initial stack pointer pointing to the end of RAM is what you would expect, as the stack must grow downwards.