μC/OS-Ⅱ总是运行进入就绪态任务中优先级最高的那一个。
每个任务的就绪态标志都放入就绪表中,就绪表中有两个变量OSRdyGrp和OSRdyTbl[]。通过这两个变量和优先级判定表OSUnMapTbl[256]来确定该哪个任务运行。
任务级的调度是由函数OSSched()完成的,中断级的调度是由OSIntExt()完成的。在任务调度过程中调用了任务切换函数OSCtxSw()。OSSched()的所有代码都属于临界区代码,所以要做关中断的工作。
μC/OS-Ⅱ为了可读性和可移植性,采用了一些C语言,但是实际工作中为了缩短任务切换的时间,此函数的代码可以全部用汇编写。所谓任务切换,其实要做的就是CPU寄存器内容切换(如图1所示)。

图1 任务切换
当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态(Context),即CPU寄存器中的全部内容。这些内容保存在任务的当前状况保存区,也就是任务自己的栈区之中。入栈工作完成以后,就是把下一个将要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行。
任务切换由以下两步完成:
(1)将被挂起任务的微处理器寄存器推入堆栈;
(2)将较高优先级的任务的寄存器值从栈中恢复到寄存器中。
在μC/OS-Ⅱ中,就绪任务的栈结构总是看起来跟刚刚发生过中断一样,所有微处理器的寄存器都保存在栈中。为了做任务切换,运行OS_TASK_SW(),人为模仿了一次中断。多数微处理器有软中断指令或者陷阱指令TRAP来实现上述操作。中断服务子程序或陷阱处理,也称作事故处理,必须提供中断向量给汇编语言函数OSCtxSw()。OSCtxSw()除了需要OSTCBHighRdy指向即将被挂起的任务,还需要让当前任务控制块OSTCBCur指向即将被挂起的任务,OSSched()的所有代码都属临界段代码。
在寻找进入就绪态的优先级最高的任务过程中,为防止中断服务子程序把一个或几个任务的就绪位置位,中断是被关掉的。为增加可读性,可移植性和将汇编语言代码最少化,OSSched()是用C写的。