在ARM Cortex-M,MSP或PSP中使用了哪个堆栈复位?

时间:2018-08-25 01:31:57

标签: arm cortex-m stack-pointer

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

我了解到Cortex-M处理器中有两个堆栈:

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

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

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

  

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

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

线程模式

  

用于执行应用程序软件。退出重置后,处理器将进入线程模式。

处理程序模式

  

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

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

1 个答案:

答案 0 :(得分:4)

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

您没有说您使用的是哪种处理器,所以假设使用Cortex-M3。在this page的底部检查对CONTROL寄存器的描述:SPSEL位控制使用哪个堆栈,对于线程和处理程序模式默认为MSP,并且只能写在“线程”模式下。

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

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

更多上下文...

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

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

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

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