When an ARM Cortex-M processor comes out of reset, it will start executing code from the vector table located at address 0x00000000. The processor expects the first entry in the vector table to be the initial stack pointer value. This initial stack pointer value determines whether the Main Stack Pointer (MSP) or Process Stack Pointer (PSP) is used coming out of reset.
The MSP is used for thread mode execution. This is the default stack used by the processor for exceptions and interrupts. The PSP is used for handler mode execution and is intended for OS tasks or threads. By initializing the vector table entry 0 with an MSP value, code will run on MSP after reset. Alternatively, initializing it with a PSP value will cause the code to run on the PSP stack.
Main Points
- The ARM Cortex-M processor expects the first entry of the vector table, located at address 0x00000000, to be the initial stack pointer value.
- This initial stack pointer value determines if the MSP or PSP is used coming out of reset.
- The MSP is used for thread mode execution and is the default stack for exceptions/interrupts.
- The PSP is used for handler mode execution and is intended for OS tasks/threads.
- Initializing vector table entry 0 with an MSP value causes code to run on MSP after reset.
- Initializing it with a PSP value causes code to run on PSP stack.
ARM Cortex-M Vector Table
The ARM Cortex-M processor begins execution at the reset vector located at address 0x00000000 after coming out of reset. This reset vector is the first entry in the vector table. The vector table contains exceptions and interrupt vectors that point to handler code.
The processor expects the first entry of the vector table to be the initial value for the stack pointer register. This determines whether the Main Stack Pointer (MSP) or Process Stack Pointer (PSP) is used initially after reset.
Vector Table Format
The vector table format is as follows:
- 0x00000000 – Initial Stack Pointer Value (MSP or PSP)
- 0x00000004 – Reset Vector
- 0x00000008 – NMI Interrupt Vector
- 0x0000000C – HardFault Interrupt Vector
- …
- 0x000003DC – Configurable interrupt 80 Vector
Initial Stack Pointer Usage
By initializing the first entry of the vector table (address 0x00000000) with an MSP value, the processor will use the MSP stack when coming out of reset. If it is initialized with a PSP value, the PSP stack will be used instead.
Main Stack Pointer (MSP)
The Main Stack Pointer (MSP) is used for thread mode execution on the ARM Cortex-M processor. Thread mode is the default execution mode, used for handling exceptions and interrupts.
When the processor enters an exception or interrupt handler, it automatically switches to using the MSP. The existing context (stack frame) is stored to the current stack pointer, and the MSP is used for the duration of the handler.
Upon returning from the handler, the previous stack frame is restored from the MSP and execution resumes in thread mode with the original stack pointer restored.
So the MSP is intended as the main stack for thread mode execution, exception and interrupt handling.
MSP Usage
- Used for thread mode execution (default)
- Used when entering exception/interrupt handlers
- Automatic switch to MSP upon exception entry
- Original stack pointer restored upon handler return
- Intended as default stack for thread mode and exception handling
Process Stack Pointer (PSP)
The Process Stack Pointer (PSP) is used for handler mode execution on the Cortex-M processor. Handler mode is intended for use by operating system tasks or threads.
To use the PSP, privileged code has to manually change to the PSP stack before starting an OS thread. The original MSP stack frame is still maintained and can be restored later.
Since switching between the PSP and MSP requires privileged access, this allows OS threads to keep separate stack spaces. Exceptions and interrupts will still use the MSP in handler mode.
PSP Usage
- Used for handler mode execution
- Intended for use by OS tasks/threads
- Requires privileged code to manually switch to PSP
- Original MSP stack frame is maintained
- Allows OS threads separate stack spaces
- Exceptions still use MSP stack
Determining Initial Stack After Reset
To determine which stack pointer is used initially coming out of reset, look at the value programmed at the first vector table entry, address 0x00000000.
- MSP value – Code uses MSP after reset
- PSP value – Code uses PSP after reset
For example, if 0x00000000 is initialized with 0x20005000, the MSP will be used initially coming out of reset.
If it is initialized with a different value like 0x20004000, then the PSP will be used instead.
So the stack used after reset can be selected by configuring the first vector table entry appropriately.
Configuring Initial Stack Pointer
There are a few common ways to configure the initial stack pointer value in the ARM Cortex-M vector table:
- Linker script – Define the stack memory region and set the vector table entry to point to the start of stack memory.
- Startup code – Initialize the vector table entry 0 in code before jumping to the main application.
- Bootloader – A bootloader can initialize the vector table entry before launching the application.
For example, in a linker script: STACK_SIZE = 0x400; SECTIONS { .stack : { . = ALIGN(8); . = . + STACK_SIZE; PROVIDE(__stack_end = .); } >RAM .vectors : { . = ALIGN(4); KEEP(*(.vectors)) /* VECTOR TABLE SECTION */ __stack_start__ = .; /* PROVIDE THE INITIAL MSP VALUE */ } > VECTORS }
This both defines a stack memory region and sets the initial MSP value to the start of that stack region in the vector table during linking.
Summary
In summary, the ARM Cortex-M processor uses either the MSP or PSP stack coming out of reset depending on the value programmed at vector table entry 0 (address 0x00000000).
Using an MSP value initializes the MSP as the active stack pointer. The MSP is used for thread mode execution and exception handling.
Alternatively, a PSP value initializes the PSP as the active stack pointer. The PSP is intended for use by operating system tasks and threads.
So the initial stack can be configured by setting vector table entry 0 appropriately to either an MSP or PSP value as required.