首页 > 代码库 > 任务的调度与切换(uC/OS-II)

任务的调度与切换(uC/OS-II)

一、任务的状态

任务的5种状态:休眠态、就绪态、运行态、挂起态(等待某一事件发生)和被中断态。

1、休眠态

任务驻留在内存中,但并不被多任务内核所调度。

2、就绪态

任务已经准备好,可以运行,但由于该任务的优先级比正在运行的任务的优先级低,暂时不能运行。

3、运行态

任务掌握了CPU的使用权,正在运行中。

4、挂起态

也叫等待事件态,指任务在等待某一事件的发生。例如:等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用状态,等待定时脉冲的到来,以结束目前的等待。

5、被中断态

发生中断时,CPU提供相应的中断服务,原来正在运行的任务暂不能运行。

 

 

二、任务的调度

任务级的调度是由函数OS_Sched()完成的。uC/OS-II任务调度的执行时间是常数,与应用程序建立了多少个任务没有关系。

 1 void  OS_Sched (void) 2 { 3 #if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */ 4     OS_CPU_SR  cpu_sr; 5 #endif     6     INT8U      y; 7  8  9     OS_ENTER_CRITICAL();10     if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked    */11         y             = OSUnMapTbl[OSRdyGrp];          /* Get pointer to HPT ready to run              */12         OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);13         if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy     */14             OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];15             OSCtxSwCtr++;                              /* Increment context switch counter             */16             OS_TASK_SW();                              /* Perform a context switch                     */17         }18     }19     OS_EXIT_CRITICAL();20 }

(1)OS_Sched()检验这个优先级最高的任务是否是当前正在运行的任务,以避免不必要的任务调度。

(2)统计计数器OSCtxSwCtr的使用目的是让用户知道每秒做了多少次任务切换。

(3)调用OS_TASK_SW()宏,完成实际上的任务切换。

 

三、任务级的任务切换

任务切换代码须恢复该任务在CPU使用权被剥夺时保存下来的全部寄存器的值,以便让这个任务能继续运行。任务切换由2步完成:将被挂起任务的处理器寄存器推入堆栈,然后将较高优先级任务的寄存器值从栈中恢复到寄存器。OS_TASK_SW()挂起了正在执行的任务,而让CPU执行更重要的任务。

 

任务切换过程增加了应用程序的额外负荷,CPU的内部寄存器越多,额外负荷越重。任务切换所需时间取决于CPU有多少寄存器要入栈

 

OS_TASK_SW()是宏调用,通常含有微处理器的软中断指令,因为uC/OS-II假定任务切换是靠软中断完成的。OS_TASK_SW()通常是汇编语言写的,因为C编译器不能从C语言中直接处理CPU寄存器。

任务的调度与切换(uC/OS-II)