【发布时间】:2019-12-03 18:18:54
【问题描述】:
如果较高优先级的任务正在等待一个事件,而较低优先级的任务正在运行。在滴答中断高优先级任务准备好之前,那么在滴答中断之前上下文切换将如何发生?直到滴答中断更高优先级的任务将等待滴答中断上下文切换?
我需要知道,在 freertos 中,上下文切换仅在滴答中断时发生?如果不是,那么高优先级任务如何在滴答中断之前抢占低优先级任务,如果它在滴答中断之前准备好?
【问题讨论】:
标签: freertos
如果较高优先级的任务正在等待一个事件,而较低优先级的任务正在运行。在滴答中断高优先级任务准备好之前,那么在滴答中断之前上下文切换将如何发生?直到滴答中断更高优先级的任务将等待滴答中断上下文切换?
我需要知道,在 freertos 中,上下文切换仅在滴答中断时发生?如果不是,那么高优先级任务如何在滴答中断之前抢占低优先级任务,如果它在滴答中断之前准备好?
【问题讨论】:
标签: freertos
如果在 FreeRTOSConfig.h 中将 configUSE_PREEMPTION 设置为 1,则 FreeRTOS 将始终运行能够运行的最高优先级任务,即使任务可在滴答中断之间运行也是如此。发生这种情况是因为发送解除阻塞任务的事件需要您调用 FreeRTOS API 函数,并且上下文切换发生在 API 函数中。我会推荐reading the free book 以了解有关调度策略的更多信息。
(这里已经提供了回复https://forums.freertos.org/t/freertos-context-switch/8333)
【讨论】:
为了澄清您的问题并提供更完整的答案,让我们先命名。您提到您有两个任务 - 我们称它们为 HighPriorityTask 和 LowPriorityTask。在这种情况下,LowPriorityTask 只会在 HighPriorityTask 被阻止时运行,这会在以下任一情况下发生:
HighPriorityTask 调用 vTaskDelay 函数或类似函数,明确停止其执行给定时间或永远,例如与vTaskSuspend,HighPriorityTask 调用 xQueueReceive 或类似的阻塞时间非零且队列中没有元素,HighPriorityTask 调用 xQueueSend 函数或类似函数,阻塞时间非零,队列中没有剩余空间。如果上述情况或类似情况均未发生导致HighPriorityTask 被阻止,则HighPriorityTask 将继续永远运行。这包括任务抢占(我假设您将其称为“滴答中断”),它不会导致LowPriorityTask 运行,因为两个任务的优先级不同,并且只有具有相同优先级的任务才会被赋予具有抢占的时间片。这甚至包括从HighPriorityTask 调用taskYIELD,这显式导致FreeRTOS 执行上下文切换,但在这种情况下,它要做的就是返回执行HighPriorityTask 代码,因为这仍然是最高的非阻塞当前正在执行的任务。
因此总结一下——如果你有两个不同优先级的任务处于“运行”状态,那么低优先级的任务将永远不会运行(任务抢占不会为低优先级的任务分配任何时间),除非高优先级的任务显式阻塞。
【讨论】: