上下文切换

问题描述

我正在尝试在 stm32f407 发现板中遵循实施任务计划的教程。

有四个函数,每次执行一个函数1ms,然后切换到下一个函数

教程定义了整个流程,我们将保存每个函数的每个堆栈寄存器,即这些寄存器xpsrpclrR0...R13,然后加载这个上下文切换时下一个函数到 PSP(处理器堆栈指针)的值(这将发生在 systick_handler 内部,它将以 1ms 的间隔触发)。

我不明白的是,我认为寄存器是全局的,而不是像函数内部的变量那样私有。那么他如何为每个函数保存这些寄存器值。这是给定的代码 https://github.com/niekiran/CortexMxProgramming/blob/master/Source_code/015_task_scheduler/Src/main.c 如果有人能向我简要介绍一下上下文切换部分,那么我将对我正在做的事情充满信心

谢谢

解决方法

想象一下,您可以在某个时间点拍下 CPU 的照片,并且该照片可以向您显示当时 CPU 中的各个 1 和 0。如果您有办法在将来的某个时刻将照片中的 1 和 0 恢复到 CPU 中,然后您可以让 CPU 运行,那么假设 RAM 和 ROM 内容未更改,它会继续执行原来的操作在拍摄照片的时候做。

这本质上就是上下文切换正在做的事情。它保存了 CPU 的所有“易失性上下文”:所有通用寄存器的内容(包括告诉它正在执行的指令的程序计数器,粗略地说,以及堆栈指针)以及处理器的内容状态寄存器 (PSR)。这些信息足以让 CPU 在未来某个时间从该确切点再次恢复。

在 Cortex-M 上,有两个堆栈指针,它们的存在使这个过程更容易。其中之一始终可以作为 sp (r13) 访问。本示例的配置方式是,处理程序模式代码使用 MSP(主堆栈指针),线程模式代码使用 PSP(进程堆栈指针)。寄存器 r0-r3r12lr (r14)、pc (r15) 和 PSR 在入口时被推送到活动堆栈到处理程序模式。只剩下 r4-r11 和堆栈指针(r13 在线程模式下,但现在通过特殊用途的 PSP 寄存器访问,因为处理程序正在使用 MSP)。

所以上下文切换获取PSP的值,然后r4-r11推入任务自己的堆栈,然后将更新后的任务堆栈指针的值保存在其任务中控制块。现在,CPU 在进入处理程序模式时的整个易失性上下文已保存到正在运行的任务的堆栈中,并且堆栈指针已保存在 TCB 中。剩下的就是找到一个新任务来运行,从它的 TCB 中取出它的堆栈指针,用它来弹出 r4-r11,然后在返回之前更新 PSP。在退出处理程序模式时,r0-r3r12lrpc 和 PSR 都会被硬件自动弹出。

所以是的,寄存器是“全局的”,在某种程度上,每个任务都使用相同的寄存器。但是当一个任务没有运行时,这些寄存器的内容存储在它的堆栈中,并在下一次准备运行时恢复到寄存器中。这就是上下文切换的目的。