在ARM Cortex-M,MSP或PSP中使用哪个堆栈从重置中出来?



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

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

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

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

在讨论 Cortex-M3 时,ARM 信息中心中的文档指出了以下内容:

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

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

线程模式

用于执行应用软件。处理器在复位时进入线程模式。

处理程序模式

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

好的,这就是让我感到困惑的地方。如果 MSP 在重置时使用并且始终在处理程序模式下使用,并且 PSP 在线程模式下使用,那么如果处理器在重置时处于线程模式,如何在重置时使用 MSP?

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

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

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

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

更多背景...

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

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

  • 为空闲任务的堆栈保留一些空间,并使用MSR指令使 PSP 指向此区域的顶部(这需要权限,但也必须从线程模式完成,因为SPSEL忽略处理程序模式下的写入(
  • 使用另一个MSR指令设置CONTROL寄存器中的SPSEL位,将运行代码切换为使用PSP和新准备的堆栈空间
  • 发出ISB指令,以确保所有后续指令都按需要使用PSP
  • 再次使用MSRCONTROL寄存器中设置nPRIV位,立即从线程模式中删除权限

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

最新更新