In STM32L432KC(arm cortex-m4+FPU) there are two ram memory blocks. Following is a snippet from the linker script I use.
_e_ram2_stack = ORIGIN(RAM2) + LENGTH(RAM2);
_e_ram_stack = ORIGIN(RAM ) + LENGTH(RAM );
...
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 16K
I can set main stack pointer(MSP) to use _e_ram_stack
or _e_ram2_stack
without problem. However when I try to set thread mode to use process stack pointer(PSP) I start to get INVPC
hard fault on SysTick interrupt return pop {r7, pc}
instruction.
If I subtract 112 from _e_ram_stack
or _e_ram2_stack
, only then I can start using PSP without problem. Something is preventing the use of end of memory address as top of the stack for PSP, but I couldn't find anything related to that in ARMv7-m architecture manual.
Following is the only change I did in the project code of STM32CubeIDE. Main program is just a dummy while(1) loop and only SysTick interrupt is enabled.
Reset_Handler:
ldr sp, =_e_ram_stack
ldr r0, =_e_ram2_stack
msr psp, r0
ldr r1, =2
msr control, r1
isb
Disassembly and register values are as following:
On SysTick interrupt handler entry:
On SysTick interrupt handler exit(pop {r7,pc}
causes hardfault):
In STM32L432KC data sheet in section 3.5 Embedded SRAM.
So the problem is in the linker script RAM length is given as the total of RAM1 and RAM2. And RAM2 is also mapped to be accessible after RAM1.
Linker script in the original post leads to
_e_ram2_stack
being equal to_e_ram_stack
after mapping. So MSP and PSP is using same memory location.The fix: