我在用FreeRTOS做我的一个项目,我正在阅读文档,有些东西我不明白。
我知道上下文切换是在触发tick中断时发生的,因此调度程序执行其工作并解除阻塞等待事件的任务,并选择处于就绪状态的高优先级任务。但是当任务在tick中断之前阻塞时会发生什么呢?文档似乎暗示上下文切换会立即发生(例如,两个优先级不同的任务分别调用vTaskDelay()以释放CPU时间片)。怎么会这样?我搜索了一下,但找不到任何问题的答案。
在我的FreeRTOS端口中编辑(SAMD21 Cortex-M0+),portYIELD()宏用于简单地请求SVCall异常,那么这是用于执行上下文切换的机制吗(除了在tick中断上运行的调度程序之外)?
最佳答案
有关于taskYIELD
的文档此函数可用于请求上下文切换,因此无需等待勾号。上下文切换是一种特权操作,因此通常通过软件中断来完成。在你的情况下由PendSV和SVCall。
如果所有任务都被阻塞(例如被vTaskDelay
),那么FreeRTOS正在运行Idle TaskvTaskDelay
在内部使用portYIELD
请求上下文切换,因为无法继续当前任务。
你还需要一些关于Preemptive multitasking的知识来理解这种模式下的FreeRTOS。
编辑2016-01-29:
调用delay函数会导致内部调用。因此,当前任务被阻止,FreeRTOS会重新安排到最高优先级的任务,如果没有任务可以运行(也没有被阻止)或空闲任务。
例如,呼叫taskYIELD
有两种可能队列中有某个元素,因此它被弹出队列中没有元素,因此任务切换到blocked state并为您调用YIELD,因此FreeRTOS重新安排到另一个任务。
例如,呼叫portYIELD
有两种可能队列中没有空间,因此任务被阻塞,直到有空间为止。至少有一个空闲元素,因此可以推送到队列。
从队列接收元素或将元素发送到队列可以唤醒其他更高优先级的任务,即正在执行oposite但当前被阻止的任务。FreeRTOS将立即重新安排。
这也可以通过中断处理程序来完成。您可以有正在等待某个队列的处理程序任务从中断开始,您将一些元素放入队列。中断结束后,FreeRTOS重新调度到等待该队列的任务在这项任务上有足够高的优先权只是先决条件。这样做的好处是,您不会在中断中做太多工作—只是一些清理并将项发送到队列—这是一个简短的操作。
处理中断也可以通过xQueueReceive
来完成,这是处理中断的另一种中断方式。
请阅读关于FreeRTOS fundamentals的内容。有好几章是关于它的,这是有疑问的阅读。
关于c - FreeRTOS上下文切换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41898581/