在 ARM Cortex-M、MSP 或 PSP 中使用哪个堆栈退出复位?

cDr*_*mer 2 arm cortex-m stack-pointer

我一直在阅读 ARM 信息中心的各个部分以尝试找到我的答案,但是我发现文档让我感到困惑,所以我希望这里有人可以提供帮助。

我知道 Cortex-M 处理器中有两个堆栈:

  • MSP(主堆栈指针)
  • PSP(进程堆栈指针)

我试图弄清楚 ARM 内核如何使用每一个。

ARM 信息中心中讨论 Cortex-M3 时的文档说明如下:

主堆栈在复位时使用,并且始终在处理程序模式下使用(进入异常处理程序时)。进程堆栈指针仅在线程模式下可用作当前堆栈指针。

好的,这告诉我 MSP 在重置时使用。但是,文档还说明了以下内容:

线程模式

用于执行应用软件。处理器退出复位后进入线程模式。

处理程序模式

用于处理异常。处理器在完成所有异常处理后返回线程模式。

好吧,这就是让我困惑的地方。如果在复位时使用MSP,并且总是在Handler模​​式下使用,而PSP在线程模式下使用,那么如果处理器在复位时处于线程模式,如何在复位时使用MSP?

coo*_*sed 5

简单的回答:你的最后一段是不正确的。 线程模式默认使用 MSP。

你没有说你使用的是什么处理器,所以让我们假设一个 Cortex-M3。查看本页CONTROL底部的寄存器说明:该位控制使用哪个堆栈,线程和处理程序模式默认为MSP,并且仅在线程模式下可写。SPSEL

此外,尽管这不是您问题的一部分,但默认情况下线程模式也具有特权。nPRIV在同一寄存器中设置该位使线程模式无特权。

总结:处理程序模式总是有特权的,并且总是使用 MSP。默认情况下,线程模式也是如此,但CONTROL寄存器允许对此进行更改。

多一点上下文...

例如,如果您正在编写一个小型操作系统,那么通常希望线程模式代码没有特权。如果线程模式代码使用 PSP,它也会使任务切换更容易,因为这样你的任务切换代码将不可避免地在处理程序模式下运行(通常在 Cortex-M 上的 PendSV 处理程序中),可以使用自己的堆栈,而无需影响它试图切换的任务堆栈。

为此,操作系统的初始化代码通常必须(按此顺序):

  • 为空闲任务的堆栈保留一些空间,并使用MSR指令使 PSP 指向该区域的顶部(这需要特权,但也必须在线程模式下完成,因为SPSEL在 Handler 模式下忽略写入)
  • 使用另一MSR条指令设置寄存器中的SPSELCONTROL,将运行代码切换为使用PSP和新准备的堆栈空间
  • 发出ISB指令以确保以下所有指令均按要求使用 PSP
  • MSR再次使用设置寄存器中的nPRIVCONTROL,立即从线程模式中删除特权

正在运行的线程模式代码然后成为空闲任务。