Cortex-M3/M4堆栈

一、Cortex-M3/M4堆栈操作

Cortex-M3/M4 使用的是“向下生长的满栈”模型。堆栈指针 SP 指向最后一个被压入堆栈的 32 位数值。在下一次压栈时, SP 先自减 4, 再存入新的数值,如图所示为堆栈的PUSH操作。
Cortex-M3/M4堆栈_第1张图片

 POP 操作刚好相反:先从 SP 指针处读出上一次被压入的值,再把 SP 指针自增 4。

Cortex-M3/M4堆栈_第2张图片

在进入 ISR 时, CM3/CM4 会自动把一些寄存器压栈,这里使用的是进入 ISR 之前使用的 SP 指针(MSP 或者是 PSP)。离开 ISR 后,只要 ISR 没有更改过 CONTROL[1],就依然使用先前的SP 指针来执行出栈操作。

二、双堆栈操作

CM3/CM4 的堆栈是分为两个:主堆栈和进程堆栈, CONTROL[1]决定如何选择。

当CONTROL[1]=0 时,只使用 MSP,此时用户程序和异常 handler 共享同一个堆栈。这也是复位后的缺省使用方式,如图所示。

Cortex-M3/M4堆栈_第3张图片当 CONTROL[1]=1 时,线程模式将不再使用 PSP,而改用 MSP(handler 模式永远使用MSP)。此时,进入异常时的自动压栈使用的是进程堆栈,进入异常 handler 后才自动改为MSP,退出异常时切换回 PSP,并且从进程堆栈上弹出数据,如图所示。

Cortex-M3/M4堆栈_第4张图片

 在特权级下,可以指定具体的堆栈指针,而不受当前使用堆栈的限制,示例代码如下:

MRS R0, MSP ; 读取主堆栈指针到 R0
MSR MSP, R0 ; 写入 R0 的值到主堆栈中
MRS R0, PSP ; 读取进程堆栈指针到 R0
MSR PSP, R0 ; 写入 R0 的值到进程堆栈中

通过读取 PSP 的值, OS 就能够获取用户应用程序使用的堆栈,进一步地就知道了在发生异常时,被压入寄存器的内容,而且还可以把其它寄存器进一步压栈的书写形式)。 OS 还可以修改 PSP,用于实现多任务中的任务上下文切换。

你可能感兴趣的:(UCOS实时操作系统,笔记,实时操作系统)