Two stack pointers
A normal microcontroller has only one stack pointer. But the Cortex-M3 has two stack pointers (SP).Number 13 of the general-purpose register is SP.R13 (SP) is composed of bank registers that switch between the main stack (SP_main) and the process stack (SP_process).
Only one stack, either SP_process or SP_main, can be seen by the user as R13.
In handler mode, SP_main is always used.In threaded mode, you can use either SP_main or SP_process.In thread mode, by using the MSR instruction to write to CONTROL, the It is possible to switch from the main stack to the process stack, and the In addition, the EXC_RETURN value can be used for selection when exiting from the handler mode.
Normally, instructions are executed in threaded mode before exceptions (interrupts and faults) occur.This means that the user can choose which stack to use at this time.However, once an exception (interrupt or fault) occurs and Cortex-M3 goes into handler mode, Cortex-M3 will only use SP_main.For example, if more interrupts occur during the execution of an interrupt service routine and the interrupt is nested, SP_main is always used.
Like other microcomputers, there is no problem at all even if only one of the stack pointers is SP_main.However, if you use SP_process when in thread mode and SP_main when in handler mode, you can protect the value of the OS stack from being corrupted by user program runaway when using the OS.
The initial value of SP_main is specified in the vector table.
In a normal microcomputer, the value of the stack pointer is written in the initialization routine in the program code and is set when the code is executed.However, in Cortex-M3, the initial value of SP_main is written to the youngest address of the vector table.
The youngest address in the vector table of a normal microcomputer contains the value of the reset start address, but In Cortex-M3, the initial value of SP_main is followed by the reset start address, so be careful.This is a convenient method for the user because it does not have to be defined in the initialization routine in the program code.
In Cortex-M3, the hardware automatically stacks the MCU states (contexts) when an exception is raised.The contexts that are stacked at this time are the link register (R14) and the program counter PC (R15) and the program status register (xPSR) and some of the general purpose registers.The Cortex-M3 has 13 general-purpose registers (R0 to R12).The stacked registers are R0 to R3 and R12.Please note that R4 to R11 are not stacked.
The Arm Architecture includes the AAPCS: Arm Architecture Procedure Call Standard and is stacked in accordance with this standard.The order in which the stack is pushed is as follows.At this time, SP ignores writing to bit [1:0], so it automatically aligns to the word on the 4-byte boundary.Note that the order in which they are pushed and the contents (positional relationship) of the stack are different.
- Program Counter (PC)
- Program Status Registers (xPSR)
- Link register (LR)
After Stuck King
Interrupts are accepted and stacking and vector fetching are done simultaneously.Then, the interrupt service routine is initiated.At this time, the register is updated, so I will explain it briefly.
First, the stack pointer R13 (SP_main or SP_process) is updated to a new address during stacking, but once the interrupt service routine starts, the main stack (SP_main) will be used.This means that the Cortex-M3 has moved into handler mode.
The PC (R15) finishes fetching the vector and is changed to the vector address by the handler.Fetch the instruction from its vector address.The interrupt PSR field (ISR number) in the xPSR indicates the interrupt handling routine (ISR) number of the currently active exception, so When you move to a new interrupt service routine, it changes to a new exception number.LR(R14) contains EXC_RETURN, a special value that is used when recovering from an exception.
In addition, the registers of the Nested Vectored Interrupt Controller (NVIC) are also updated according to the type of interrupt.(The details of the register are explained in the interrupt section.)
Exiting the Exception
When the exception is handled, the handler will return to thread mode.The procedure is done in the reverse of the stack, but briefly described as follows
First, the register is popped.Pop the PC, xPSR, R0, R1, R2, R3, R12, and LR from the stack.The order of the pops is the same as the stacking, and the SP is also restored.If the interrupt is nested, it will go to another exception, but SP will remain on the main stack (SP_main).To return to thread mode, SP is the main stack (SP_main) or process stack (SP_process) that was selected before the interrupt was entered.And the registers for the Nested Vectored Interrupt Controller (NVIC) are also restored.
For more information about the state transitions of interrupt processing, see the「Part 13: EDIANS, memory format, data type, exception/interrupt handling」for more information.
This post is also available in: Japanese