前言
在第7章我们知道在创建任务并启动任务调度器后,当前任务控制块是指向第一个任务(即pxCurrentTCB = &Task1TCB),然后会产生SVC中断,将pxCurrentTCB出栈至CPU寄存器切换至任务1。
在任务1函数的最后会执行taskYield,taskYield会产生PendSVC中断,先将任务1入栈,然后将当前任务控制块指向第二个任务(即pxCurrentTCB = &Task2TCB),再将pxCurrentTCB出栈至CPU寄存器切换至任务2。在任务2函数的最后也是如此切换至任务1。
本章知识点
在本章,在启动任务调度器时,还会同时把空闲任务创建起来,并启动滴答定时器及其中断,然后在产生的SVC中断中切换至任务1。在滴答定时器中断中会先将所有任务的倒计时个数减1,再调用taskYield完成任务切换,如下图:
在任务1函数中,会通过vTaskDelay函数来给当前任务赋以倒计时个数(即延时时长)并调用taskYield完成任务切换,如下图:
注意这里taskYield产生PendSVC中断中的任务切换不再是任务1时切任务2这样简单了,而是会通过一个复杂一些的算法来切换,如下代码:
void vTaskSwitchContext( void )
{
if ( pxCurrentTCB == &IdleTaskTCB )
{
if (Task1TCB.xTicksToDelay == 0)
{
pxCurrentTCB =&Task1TCB;
}
else if (Task2TCB.xTicksToDelay == 0)
{
pxCurrentTCB =&Task2TCB;
}
else
{return;}
}
else
{
if (pxCurrentTCB == &Task1TCB)
{
if (Task2TCB.xTicksToDelay == 0)
{
pxCurrentTCB =&Task2TCB;
}
else if (pxCurrentTCB->xTicksToDelay != 0)
{
pxCurrentTCB = &IdleTaskTCB;
}
else
{return;}
}
else if (pxCurrentTCB == &Task2TCB)
{
if (Task1TCB.xTicksToDelay == 0)
{
pxCurrentTCB =&Task1TCB;
}
else if (pxCurrentTCB->xTicksToDelay != 0)
{
pxCurrentTCB = &IdleTaskTCB;
}
else
{return;}
}
}
}
举例
最后的波形应该是这样的,如下:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)