Embedded 在Cortex-M上的ISR内切换上下文

Embedded 在Cortex-M上的ISR内切换上下文,embedded,arm,cortex-m3,Embedded,Arm,Cortex M3,我正在尝试使用CodeSourcery GCC工具链为Cortex-m编写一个基本的循环调度程序。我的调度程序使用SysTick在时间片到期后触发中断,并且在ISR内进行上下文切换。为了简单起见,我对所有内容都只使用主堆栈指针(MSP) 我一直在决定如何处理在Cortex-M3上加载新上下文。根据Cortex-M3技术参考手册(TRM),该过程将PC、LR和状态寄存器推送到ISR入口的当前堆栈上 如果我按下其余寄存器以保存当前任务的上下文,并从下一个任务的控制块加载新的SP值,我将如何恢复其上下

我正在尝试使用CodeSourcery GCC工具链为Cortex-m编写一个基本的循环调度程序。我的调度程序使用SysTick在时间片到期后触发中断,并且在ISR内进行上下文切换。为了简单起见,我对所有内容都只使用主堆栈指针(MSP)

我一直在决定如何处理在Cortex-M3上加载新上下文。根据Cortex-M3技术参考手册(TRM),该过程将PC、LR和状态寄存器推送到ISR入口的当前堆栈上

如果我按下其余寄存器以保存当前任务的上下文,并从下一个任务的控制块加载新的SP值,我将如何恢复其上下文的其余部分

据我所知,我需要弹出我推送的寄存器(比如{r4-r11}),处理器将在ISR返回时自动推送其余寄存器(包括新任务(LR)的返回地址和状态寄存器)。所以我假设我只需要在完成任务切换后执行一个
BX

下面是TRM上的内容:

当以下指令之一在1)POP/LDM(包括将PC作为目标加载到PC 2)LDR 3)BX和任何寄存器时,将0xFFFFFx的值加载到PC时发生异常返回

如何加载EXC_返回值?我是否应该把它推到堆栈上(就像它应该做的那样)?假设我已经弹出了通过软件推送的寄存器,大脑皮层如何弹出它保存的寄存器?通常,如何恢复任务的上下文


我试着阅读了TRM和其他ARM参考资料,但它们似乎不清楚。

阅读了更多关于#ARM IRC频道的内容和一些帮助,之后我能够理解异常返回机制。以下是我的理解

如CM3 TRM中所述,当注册异常时,内核将寄存器r0-r3、r12以及状态、LR和PC推送到当前进程堆栈上。因此,在异常输入时,堆栈包含8个字,其中包括包含要返回的地址的LR。硬件弹出机制实质上逆转了相同的动作,即弹出最后8个字,在此期间,它将LR加载到PC中,以返回中断的功能

因此,只需将堆栈指针移动到适当的位置即可切换上下文,以使当前堆栈帧类似于刚刚中断的任务的堆栈帧,即包含相同顺序的确切单词


在异常输入时,在将寄存器保存到堆栈上后,LR将加载EXC_返回值。此值包含指示返回条件的特殊状态标志。这也用于指示中断的结束。也就是说,如果ISR需要返回到任务并将堆栈指针从当前(MSP)切换到PSP,它可以使用适当的EXC_值(在TRM中指示)加载LR,只需执行一个
BX LR
来切换状态。

下面是一个代码片段,它完全满足您的需要--它的工作方式如您所述:

  • 异常条目自动堆叠一些寄存器
  • 手动堆叠剩余寄存器
  • 您切换SP
  • 取消“剩余”寄存器的堆栈
  • 异常返回将取消剩余寄存器的堆栈

这确实相当复杂。我正在写一本关于运行在Cortex-M内核上的FreeRTOS操作系统的书。我已经为此写了一章。通过阅读您的问题,我相信本章将帮助您:


存储在isr中堆栈上的数据表示先前上下文的状态是吗?因此,加上您需要保留为旧上下文状态的任何其他寄存器,用新上下文状态替换这些寄存器(包括上次交换时新上下文中的0xFFFf…值),然后从中断返回例如,似乎解释了一切?你不明白什么?是的,图表很清楚,但我不明白的是a)硬件弹出机制是什么,它是否只是弹出最后8个左右的单词,然后返回到这些单词中包含的LR?我们在哪里写EXC_返回值?显然,链接只是将其写入堆栈。@Shrikant Giridhar我已经发布了FreeRTOS如何在Cortex-M7上进行上下文切换的完整描述。我相信Cortex-M7和Cortex-M3非常相似,除了M7中的浮点单元和一些额外的速度和外围设备。我希望这个描述对你有用。问候