在ARM Cortex-M、MSP或PSP中,重置后使用哪个堆栈?

在ARM Cortex-M、MSP或PSP中,重置后使用哪个堆栈?,arm,cortex-m,stack-pointer,Arm,Cortex M,Stack Pointer,我一直在阅读ARM信息中心的各个部分,试图找到我的答案,但是我到了一个地步,文档把我弄糊涂了,所以我希望这里的人能帮助我 我知道Cortex-M处理器有两个堆栈: MSP(主堆栈指针) PSP(进程堆栈指针) 我想弄清楚每一个都是如何被ARM核心使用的 在讨论Cortex-M3时,ARM信息中心的文档说明如下: 主堆栈在重置时使用,并且始终在处理程序模式下使用(当输入异常处理程序时)。进程堆栈指针仅在线程模式下作为当前堆栈指针可用 好的,这告诉我MSP在重置时使用。但是,文件中还规定了以下内

我一直在阅读ARM信息中心的各个部分,试图找到我的答案,但是我到了一个地步,文档把我弄糊涂了,所以我希望这里的人能帮助我

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

  • MSP(主堆栈指针)
  • PSP(进程堆栈指针)
我想弄清楚每一个都是如何被ARM核心使用的

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

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

好的,这告诉我MSP在重置时使用。但是,文件中还规定了以下内容:

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

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


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

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

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

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

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

多一点上下文…

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

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

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

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

注意,对于某些cortex ms,只有一个堆栈指针。你必须积极地使用另一个堆栈指针,如果你不想同时使用这两个堆栈指针,那么什么都不要做,你只需要一个。使用另一个堆栈指针有点痛苦,你真的需要这样做