通过分析任务切换,我们知道任务切换的两种方法:系统节拍器中断、调用portYIELD产生PendSV中断。
在系统节拍器中断中,如果调度器被挂起,仅仅将调度器挂起时间加一(在解除挂起后需要补偿这些节拍),并不会检查是否有任务需要切换。
/* 系统节拍加一 */
BaseType_t xTaskIncrementTick(void)
{
BaseType_t xSwitchRequired = pdFALSE;
/* 调度器没有被挂起 */
if(uxSchedulerSuspended == (UBaseType_t)pdFALSE)
{
......
}
/* 调度器被挂起 */
else
{
/* 挂起时间加一 */
++uxPendedTicks;
}
/* 前面有程序因为各种原因,要求延迟到现在切换 */
if(xYieldPending != pdFALSE)
{
/* 请求切换任务,最终进入PendSV异常,是否切换上下文还是在于PendSV */
xSwitchRequired = pdTRUE;
}
return xSwitchRequired;
}
在PendSV中断中,如果调度器被挂起,则不进行上下文切换,通过xYieldPending将任务切换延迟到下一个节拍。
/* 任务切换上下文 */
void vTaskSwitchContext(void)
{
/* 调度器被挂起 */
if(uxSchedulerSuspended != (UBaseType_t)pdFALSE)
{
/* 等到下一次节拍的时候再切换上下文 */
xYieldPending = pdTRUE;
}
/* 调度器没有挂起 */
版权声明:本文为lushoumin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。