if (OSRunning == OS_TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) {
OSIntNesting--;
}
if (OSIntNesting == 0) {
if (OSLockNesting == 0) {
OS_SchedNew(); //计算处于最高优先级的任务
if (OSPrioHighRdy != OSPrioCur) { //假如就绪态的任务优先级高于当前运行的任务优先级着将其调度执行
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN > 0
OSTCBHighRdy->OSTCBCtxSwCtr++;
#endif
OSCtxSwCtr++;
OSIntCtxSw(); //任务切换
}
}
}
OS_EXIT_CRITICAL();
}
}
LDMFD SP!,{R4} //将当前堆栈保存的数据弹出一个到R4,即将被中断的任务的CPSR保存到R4
MSR SPSR_cxsf,R4
LDMFD SP!,{R0-R12,LR,PC}^ 出栈,继续执行被中断的任务。
OSInt和OS_Sched类似但是不能互换使用。OSIntExit含有中断嵌套数的计算。在OSIntExit做任务切换使用的是OSIntCtxSw,而OS_Sched中使用的是OS_TASK_SW。根据如上分析,每个时钟片刻结束时候OS都会根据优先级重新调度一遍,所以说在μC/OS,只要高优先级的任务处于就绪态,就会立即抢占CPU。以为在这一个时钟片结束后,OS会执行一次调度。