我正在尝试遵循在stm32f407发现板中实现任务调度的教程。
有四种功能,一次执行一次,每次1ms,然后切换到下一个函数。
教程定义了整个流程,我们将保存每个函数的每个堆栈寄存器,即这些寄存器xpsr、pc、lr、R0...R13,然后在上下文切换时将下一个函数的这个值加载到PSP (处理器堆栈指针)(这将发生在systick_handler内部,在1ms的间隔内触发)。
我不明白的是,我认为寄存器是全局的,不像function.So中的变量那样是私有的,他是如何为每个函数保存这些寄存器值的。这是给定的代码https://github.com/niekiran/CortexMxProgramming/blob/master/Source_code/015_task_scheduler/Src/main.c,如果有人可以简单介绍一下上下文切换部分,那么我将对我正在做的事情非常有信心。
谢谢
发布于 2020-12-30 23:19:44
想象一下,你可以在某个时间点拍一张CPU的照片,这张照片可以在那个时刻显示CPU中的单个1和0。如果你有办法在将来的某个时候将照片中的1s和0s还原回CPU,然后你可以让CPU运行,那么假设RAM和ROM的内容没有改变,它将继续做它在照片拍摄时所做的事情。
这本质上就是上下文切换所做的事情。它保存了CPU的所有“易失性上下文”:所有通用寄存器的内容(包括告诉它正在执行的指令的程序计数器和堆栈指针)以及处理器状态寄存器(PSR)。这是足够的信息,可以让CPU在将来的某个时候从这个确切的点恢复。
在Cortex-M上,有两个堆栈指针,它们的存在使这个过程更容易。其中的一个或另一个始终可以作为sp (r13)访问。按照此示例的配置方式,处理程序模式代码使用MSP (主堆栈指针),线程模式代码使用PSP (进程堆栈指针)。寄存器r0-r3、r12、lr (r14)、pc (r15)和PSR在进入处理程序模式时被推入活动堆栈。这只剩下r4-r11和堆栈指针(r13处于线程模式,但现在通过特殊用途的PSP寄存器访问,因为处理程序正在使用MSP)。
因此,上下文开关获取PSP的值,然后在任务控制块中保存任务堆栈指针的更新值之前,将r4-r11推送到任务自己的堆栈。现在,CPU进入处理程序模式时的整个易失性上下文已经保存到正在运行的任务的堆栈中,堆栈指针已经保存在TCB中。剩下的就是找到一个要运行的新任务,从TCB中获取它的堆栈指针,使用它弹出r4-r11,然后在返回之前更新PSP。在退出处理程序模式时,硬件将自动弹出r0-r3、r12、lr、pc和PSR。
所以,是的,寄存器是“全局的”,某种程度上,每个任务都使用相同的寄存器。但是,当任务没有运行时,这些寄存器的内容将存储在它的堆栈上,并在下次准备运行时恢复到寄存器中。这就是上下文切换的目的。
https://stackoverflow.com/questions/65513811
复制相似问题