![](https://csdnimg.cn/release/download_crawler_static/7349307/bg6.jpg)
任务级切换是某个任务主动调用了 OSTimeDly()(或 OSpend()之类的)让任务进入等待状态的函数后,接着调用
OS_Sched()进行任务调度;OS_Sched()在判断
OSIntNesting == 0 && OSLockNesting == 0,即中断任务全部执行完毕后(在我看来,这两句似乎可以不要,有了更好)
如果 OSPrioHighRdy != OSPrioCur,即当前最高任务优先级发生变化时,调用 OS_TASK_SW()进行任务切
换,执行高优先级任务。OS_TASK_SW()不再返回;
如果 OSPrioHighRdy == OSPrioCur,即当前最高任务优先级没有发生变化时,OS_TASK_SW(),OS_Sched(),
OSTimeDly()依次返回,继续执行当前任务的下一条语句。
OS_Sched()需要注意两点:
OS_Sched()全部属于临界段代码,保证了在任务切换过程中不会发生中断,也不会发生任务级被中断级切
换的可能;
OS_Sched()如果调用了 OS_TASK_SW()后,OS_TASK_SW()不会返回,而 OS_Sched()函数中位于 OS_TASK_SW()
之后的恢复中断的语句得不到执行,这会发生中断是被关闭而没有恢复的情况。
4) 任务级被中断级切换(这里假设只有一级中断,否则属于第 4)中情况):
任务级被中断级切换发生在任务函数执行,等待状态中。
任务级被中断以后:
当前任务被中断地方的下一条语句压入栈中;PUSH 寄存器,PUSH PSW
OSIntNesting++,if(OSIntNesting==1) , OSTCBCur->OSTCBStkPtr=SP;
If(OSIntNesting == 0 && OSLockNesting == 0) 即中断任务全部执行完毕后,
求出当前最高优先级任务 OSPrioHighRdy:
如果 OSPrioHighRdy != OSPrioCur,即当前最高任务优先级发生变化时,调用 OSIntCtxSw()进行任务
切换。然后执行更高优先级的任务,OSIntCtxSw()函数不返回(OSIntExit()当然也不返回),可以理
解为直接 return 了。这种情况下,其实 OSIntExit()后的 pop ,reti 操作就不会别执行。
如果 OSPrioHighRdy == OSPrioCur,即当前最高任务优先级没有发生变化,OSIntCtxSw()不会被执行,
OSIntExit()返回,执行 pop ,reti 等,这样恢复 CPU 寄存器,断点等,接着程序被中断的地方执行。
OSIntExit()也需要注意,它和 OS_Sched()具有相同的特性。
中断级被更高中断级别切换发生在中断函数中,重新开启中断之后,调用 OSIntExit()之前。
每次中断:
当前任务被中断地方的下一条语句压入栈中;PUSH 寄存器,PUSH PSW
OSIntNesting++,if(OSIntNesting==1) , OSTCBCur->OSTCBStkPtr=SP;
如果不是最后级中断退出 OSIntNesting>0, OSIntExit()会直接返回,执行 pop,reti 来恢复上一次被中断的中断函数,直到最
后一级中断退出,见上述 3)中的情况
1)每个任务都会保存一份 PSW,在任务恢复时,PSW 也需要恢复。
2)中断的打开、关闭很频繁。关闭后都需要相应的打开操作,并且关闭中断的
具体来说:
1)任务恢复时,需要恢复 PSW
第一次任务被调度时,恢复 PSW 的值是在通过 OSTaskStkInit()保存任务堆栈中的。为了防止在某个任务在第一次被调