有一个FreeRTOS library for Arduino,据称甚至可以在UNO上运行。
我试图了解如何在这样有限的硬件上运行多任务操作系统的内部工作原理。我了解任务调度/切换的原理,但是内核实际上是如何暂停一个任务以执行另一个任务?它如何中断(然后再恢复)当前正在执行的代码?
我的猜测是,预定的ISR(定时器)直接修改堆栈以更改指令指针,但是如果这样做,则需要在切换任务之前制作堆栈的副本并进行注册,然后恢复当前任务的堆栈/在恢复执行之前注册。我尚不清楚它将如何做到这一点。
例如,在Serial.println()
函数调用(或任何不包含cli()
的调用)中,FreeRTOS内核可以切换任务吗? ?
感谢您的澄清。
答案 0 :(得分:1)
我的猜测是,预定的ISR(定时器)直接修改堆栈以更改指令指针,但是如果这样做,则需要在切换任务之前制作堆栈的副本并进行注册,然后恢复当前任务的堆栈/在恢复执行之前注册。我尚不清楚它将如何做到这一点。
您的猜测是正确的。如果查看port.c,您会发现FreeRTOS makros portSAVE_CONTEXT
和portRESTORE_CONTEXT
分别是 pushhes 和 pops 当前运行的所有寄存器任务以执行任务切换。此外,看门狗定时器中断用于运行调度程序。
只要启用并触发了该看门狗定时器,任务切换就可以随时发生。因此,在诸如Serial.println
之类的任何函数调用期间也可能发生切换。这意味着,如果您从多个任务中调用此函数,则迟早会破坏串行流的输出。