我正在将 FreeRTOS 用于我的一个项目,我正在阅读文档,但有一些我无法理解的内容。我知道上下文切换发生在滴答中断被触发时,因此调度程序执行其工作并取消阻塞等待事件的任务并选择处于就绪状态的更高优先级任务。但是当任务在滴答中断之前阻塞时会发生什么?该文档似乎暗示上下文切换会立即发生(例如,两个具有不同优先级的任务,每个任务都调用 vTaskDelay() 以释放 CPU 时间片)。它是如何发生的?我进行了搜索,但找不到我的问题的任何答案。
EDIT在我FreeRTOS的(SAMD21的Cortex-M0 +)的端口的portYIELD()宏用于简单地请求SVCall异常,所以这是一个用于(从蜱中断运行调度预留)执行上下文切换的机制?
有关于taskYIELD
. 此函数可用于请求上下文切换,因此无需等待滴答声。上下文切换是特权操作,因此通常通过软件中断来完成。在你的情况下,PendSV 和 SVCall。
如果所有任务都被阻止(例如被vTaskDelay
),则 FreeRTOS 正在运行Idle Task。vTaskDelay
在portYIELD
内部使用来请求上下文切换,因为没有办法如何继续当前任务。
您还需要一些有关抢占式多任务处理的知识才能了解该模式下的 FreeRTOS。
编辑 2016-01-29:
taskYIELD
/portYIELD
内部。因此,您当前的任务被阻止,FreeRTOS 将重新安排到最高优先级的任务,该任务可以运行(也不会被阻止),或者如果没有能够运行的任务,则重新安排为空闲任务。xQueueReceive
有两种可能性。队列中有一些元素,所以它是 POP 的。队列中没有元素,因此任务切换到阻塞状态并为您调用 YIELD,因此 FreeRTOS 重新分配到另一个任务。xQueueSend
有两种可能性。队列中没有空间,因此任务被阻塞,直到有空间。至少有一个空闲元素,因此您可以推送到队列。从队列接收元素或向队列发送元素可以唤醒其他更高优先级的任务,即正在执行相反操作但当前被阻塞的任务。FreeRTOS 将立即重新安排它。
这也可以从中断处理程序完成。您可以有处理程序任务,即在某个队列上等待。从中断开始,您将一些元素放入队列。中断结束后,FreeRTOS 会重新安排在该队列上等待的任务。只有在该任务上具有足够高的优先级的先决条件。这有好处,您在中断中没有做太多事情 - 只是一些清理并将项目发送到队列 - 这是简短的操作。处理中断也可以通过 来完成xTimerPendFunctionCallFromISR
,这是如何处理中断的另一种有趣的方式。
另请阅读有关FreeRTOS 基础知识的信息。有好几章是关于它的,读起来很有趣。