I am using ARM-GCC compiler and I found on Internet two versions for the startup_stm32f10x_cl.c file (startup code). The processor is: STM32F105RC (ARM Cortex M3).
Common part :
#define STACK_SIZE 0x100 /*!< The Stack size */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];
Then, the first version starts the vector table like this:
void (* const g_pfnVectors[])(void) =
{
(void *)&pulStack[STACK_SIZE], /*!< The initial stack pointer */
Reset_Handler, /*!< Reset Handler */
...
while the second version looks like this:
void (* const g_pfnVectors[])(void) =
{
(void *)&pulStack[STACK_SIZE - 1], /*!< The initial stack pointer */
Reset_Handler, /*!< Reset Handler */
...
So, my question is:
Which one is the correct stack pointer initialization?
Defines the Stack Pointer selection: When this bit is 0 (default), Thread mode uses Main Stack Pointer (MSP). When this bit is 1, Thread mode uses Process Stack Pointer (PSP). In Handler mode, this bit is always 0 and write to this bit is ignored.
To set up the stack pointers, enter each mode with interrupts disabled, and assign the appropriate value to the stack pointer. The stack pointer value set up in the reset handler is automatically passed as a parameter to __user_initial_stackheap() by C library initialization code.
After reset, the stack pointer is initialized to 7h. The stack will start growing up from address 8h. The Keil C compiler uses internal DATA memory for your variables and also allows you to use register banks 1, 2, and 3.
To allocate space on the stack, the stack pointer is decremented (i.e. the stack grows down). Thus, in order to use the buffer STACK for the stack, the stack pointer has to initially point to the end of STACK so decrementing the stack pointer makes it point to new parts of STACK .
From ARM documentation for M3 cores instruction-set:
PUSH uses the value in the SP register minus four as the highest memory address
and
On completion, PUSH updates the SP register to point to the location of the lowest stored value
So, my interpretation is that the starting point of SP must be +4 of the highest address, i.e. the address immediately after the Stack array bounds. Hence
(void *)&pulStack[STACK_SIZE]
looks right, as that address (although not part of the array), will never be used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With