Embedded ISR中的操作系统上下文切换

Embedded ISR中的操作系统上下文切换,embedded,operating-system,Embedded,Operating System,我只是想知道,当某个异步事件引发ISR,使更高优先级的任务准备好运行时,操作系统实际上是如何进行上下文切换的。据我所知,当CPU输入ISR时,它会将一些寄存器值放入硬件堆栈,那么调度器如何检索这些值并将其放入任务堆栈?它是否访问硬件堆栈以复制allready保留的值?我希望我是清楚的 提前感谢。在Cortex-M3处理器上,您有MSP(主堆栈指针-硬件堆栈)和PSP(进程堆栈指针-任务堆栈) 进入异常时,堆栈帧存储在当前PSP堆栈上(在正常、非嵌套操作中)。然后,异常处理程序切换到MSP堆栈,但

我只是想知道,当某个异步事件引发ISR,使更高优先级的任务准备好运行时,操作系统实际上是如何进行上下文切换的。据我所知,当CPU输入ISR时,它会将一些寄存器值放入硬件堆栈,那么调度器如何检索这些值并将其放入任务堆栈?它是否访问硬件堆栈以复制allready保留的值?我希望我是清楚的


提前感谢。

在Cortex-M3处理器上,您有MSP(主堆栈指针-硬件堆栈)和PSP(进程堆栈指针-任务堆栈)

进入异常时,堆栈帧存储在当前PSP堆栈上(在正常、非嵌套操作中)。然后,异常处理程序切换到MSP堆栈,但是它仍然可以访问PSP堆栈,因此它可以在同一PSP堆栈上存储任何剩余的寄存器等,以及它需要的任何其他任务信息

然后,异常可以选择新的高优先级任务,并将PSP切换到此任务堆栈,并恢复所需的寄存器。然后,它使PSP保持与任务暂停时完全相同的状态,以便在从异常返回时正确恢复堆栈的其余部分

在某些情况下,它比这更复杂,但这是基本操作(在手臂皮层-M上)。在其他处理器上会有所不同


我建议下载FreeRTOS并查看各种不同的端口层。那里几乎所有东西都有一个端口,而“portable”目录中的低级任务切换内容相当小且简单。

在Cortex-M3处理器上,您有MSP(主堆栈指针-这是您的硬件堆栈)和PSP(进程堆栈指针-这是您的任务堆栈)

进入异常时,堆栈帧存储在当前PSP堆栈上(在正常、非嵌套操作中)。然后,异常处理程序切换到MSP堆栈,但是它仍然可以访问PSP堆栈,因此它可以在同一PSP堆栈上存储任何剩余的寄存器等,以及它需要的任何其他任务信息

然后,异常可以选择新的高优先级任务,并将PSP切换到此任务堆栈,并恢复所需的寄存器。然后,它使PSP保持与任务暂停时完全相同的状态,以便在从异常返回时正确恢复堆栈的其余部分

在某些情况下,它比这更复杂,但这是基本操作(在手臂皮层-M上)。在其他处理器上会有所不同


我建议下载FreeRTOS并查看各种不同的端口层。那里几乎所有东西都有一个端口,而“portable”目录中的低级任务切换内容非常简单明了。

由于我不太确定您的问题的范围,我将尝试总结一些抢占式调度的概念:

每个任务有一个堆栈。对于每个堆栈,都有一个指向它的堆栈指针。因此,基本上,对于任务开关,保存当前堆栈指针,并加载下一个任务的堆栈指针。有趣的是,从操作系统到任务代码的返回是通过
return
指令完成的,而不是像人们预期的那样通过
JUMP
调用来完成的

当ISR中断正在运行的任务时,它本身不会运行另一个任务。正如您正确地说的,它只会使一个任务可运行(将它从等待状态中取出),以便在下一个调度周期中,OS可以考虑现在就绪的任务以进一步执行。(如果和何时该任务运行取决于其分配的优先级;如果该任务具有非常高的优先级,则操作系统可能会尝试确保它在切换到任何其他优先级较低的任务之前运行。)

实际任务切换仅在ISR完成并返回后发生,因此无需将任何内容从一个堆栈复制到另一个堆栈。

在“简单”实现中,ISR可能只是返回到它中断的任务,这样就不会出现早期的“无序”上下文切换

另一个更复杂的实现可以让ISR返回操作系统,而不是中断的任务。这样就可以调用像
yield()
这样的函数,让操作系统有机会在必要时立即进行任务切换


但是,这可能需要受影响的ISR附加特殊的退出指令,以替换正常编译器生成的ISR代码。

由于我不太确定您的问题的范围,我将尝试总结一些抢占式调度的概念:

每个任务有一个堆栈。对于每个堆栈,都有一个指向它的堆栈指针。因此,基本上,对于任务开关,保存当前堆栈指针,并加载下一个任务的堆栈指针。有趣的是,从操作系统到任务代码的返回是通过
return
指令完成的,而不是像人们预期的那样通过
JUMP
调用来完成的

当ISR中断正在运行的任务时,它本身不会运行另一个任务。正如您正确地说的,它只会使一个任务可运行(将它从等待状态中取出),以便在下一个调度周期中,OS可以考虑现在就绪的任务以进一步执行。(如果和何时该任务运行取决于其分配的优先级;如果该任务具有非常高的优先级,则操作系统可能会尝试确保它在切换到任何其他优先级较低的任务之前运行。)

实际任务切换仅在ISR完成并返回后发生,因此无需将任何内容从一个堆栈复制到另一个堆栈。

在“简单”实现中,ISR可能只是返回到它中断的任务,这样就不会出现早期的“无序”上下文切换

另一个更复杂的实现可以让ISR返回操作系统,而不是中断的任务。这样就可以调用像
yield()
这样的函数,从而使操作系统有机会