18.2.1 Initialize Stack Pointer and Heap

This step is only explicitly performed for some devices. The initial stack pointer value is defined using the symbol _stack which is defined by the linker to be located in data (RAM) memory. A minimum amount of stack space is reserved by defining the symbol _min_stack_size to a positive value, e.g. by using the linker --defsym option. Note that while some implementations may locate the stack base at the highest RAM address, the XC32 linker may place it elsewhere in RAM. On devices which support placing the stack in TCM with the -mstack-in-dtcm option, the stack pointer will be updated to the new location in TCM following TCM initialization steps. See 18.2.7 Relocate Stack to TCM and 7.5 Tightly-Coupled Memories.

Although the stack pointer is initialized by hardware on Cortex-M devices, it can be initialized from the runtime startup code in cases where the application is bootloaded by other code. Note in the following example that the code is guarded by the preprocessor macro __REINIT_STACK_POINTER.

#if defined (__REINIT_STACK_POINTER)
  /* Initialize SP from linker-defined _stack symbol. */
  __asm__ volatile ("ldr sp, =_stack" : : : "sp");
#ifdef SCB_VTOR_TBLOFF_Msk
  /* Buy stack for locals */
  __asm__ volatile ("sub sp, sp, #8" : : : "sp");
 #endif
  __asm__ volatile ("add r7, sp, #0" : : : "r7");
 #endif

For Cortex-A devices, the runtime startup code sets the stack for the following modes: FIQ, IRQ, Abort, Undefined, System, and Supervisor. Once finished, the system is in Supervisor mode.