在STM32L432KC(arm cortex-m4+FPU)中有两个RAM内存块。以下是我使用的链接器脚本的片段。
_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
我可以设置主堆栈指针(MSP)来使用
_e_ram_stack
或_e_ram2_stack
,没有问题。然而,当我尝试设置线程模式以使用进程堆栈指针(PSP)时,我开始在 SysTick 中断返回 INVPC
指令上遇到 pop {r7, pc}
硬故障。
如果我从
_e_ram_stack
或_e_ram2_stack
中减去112,那么我就可以毫无问题地开始使用PSP。有些东西阻止使用内存结束地址作为 PSP 的堆栈顶部,但我在 ARMv7-m 架构手册中找不到与此相关的任何内容。
以下是我在STM32CubeIDE的项目代码中所做的唯一更改。主程序只是一个虚拟的 while(1) 循环,并且仅启用 SysTick 中断。
Reset_Handler:
ldr sp, =_e_ram_stack
ldr r0, =_e_ram2_stack
msr psp, r0
ldr r1, =2
msr control, r1
isb
拆解及寄存器值如下:
SysTick 中断处理程序退出时(
pop {r7,pc}
导致硬故障):
STM32L432KC 数据手册第 3.5 节嵌入式 SRAM。
STM32L432xx 器件具有 64 KB 嵌入式 SRAM。这个静态随机存储器是 分成两块:
48 KB 映射到地址 0x2000 0000 (SRAM1)
16 KB 位于地址 0x1000 0000,带硬件奇偶校验 (静态随机存储器2)。该内存也映射到地址 0x2000 C000,提供 与 SRAM1 的连续地址空间
所以问题出在链接描述文件中,RAM 长度是 RAM1 和 RAM2 的总和。 RAM2 也被映射为在 RAM1 之后可访问。
原帖中的链接器脚本导致映射后_e_ram2_stack
等于
_e_ram_stack
。所以 MSP 和 PSP 使用相同的内存位置。
修复:
_e_ram1_stack = ORIGIN(RAM1) + LENGTH(RAM1);
_e_ram2_stack = ORIGIN(RAM2) + LENGTH(RAM2);
...
RAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 48K # was 64K in original script
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 16K