电脑
μC/OS-Ⅱ源代码
任务控制块(Task Control Blocks, OS_TCB) 一旦任务建立了,任务控制块OS_TCBs将被赋值(程序清单3.3)。任务控制块是一个数据结构,当任务的CPU使用权被剥夺时,μC/OS-Ⅱ用它来保存该任务的状态。当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。OS_TCBs全部驻留在RAM中。读者将会注意到笔者在组织这个数据结构时,考虑到了各成员的逻辑分组。任务建立的时候,OS_TCBs就被初始化了(见第四章任务管理)。程序清单 L 3.3 μC/OS-II任务控制块.#if OS_TASK_CREAT_EXT_EN > 0typedef struct{ INT32U OSFree; //Numbers of free bytes on the stack INT32U OSUsed; //Numbers of bytes used on the stack}OS_STK_DATA;#endiftypedef struct os_tcb { OS_STK *OSTCBStkPtr;#if OS_TASK_CREATE_EXT_EN void *OSTCBExtPtr; OS_STK *OSTCBStkBottom; INT32U OSTCBStkSize; INT16U OSTCBOpt; INT16U OSTCBId;#endif struct os_tcb *OSTCBNext; struct os_tcb *OSTCBPrev;#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN OS_EVENT *OSTCBEventPtr;#endif#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN void *OSTCBMsg;#endif INT16U OSTCBDly; INT8U OSTCBStat; INT8U OSTCBPrio; INT8U OSTCBX; INT8U OSTCBY; INT8U OSTCBBitX; INT8U OSTCBBitY;#if OS_TASK_DEL_EN BOOLEAN OSTCBDelReq;#endif} OS_TCB;
就绪表(Ready List) 每个任务被赋予不同的优先级等级,从0级到最低优先级OS_LOWEST_PRIO,包括0和OS_LOWEST_PRIO在内(见文件OS_CFG.H)。当μC/OS-Ⅱ初始化的时候,最低优先级OS_LOWEST_PRIO总是被赋给空闲任务idle task。注意,最多任务数目OS_MAX_TASKS和最低优先级数是没有关系的。用户应用程序可以只有10个任务,而仍然可以有32个优先级的级别(如果用户将最低优先级数设为31的话)。 每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRdyGrp和OSRdyTbl[]。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入 就 绪态 时,就 绪表 OSRdyTbl[] 中 的 相应 元 素的 相 应位 也 置位。就绪 表 OSRdyTbl[] 数组 的 大小 取 决于OS_LOWEST_PRIO(见文件OS_CFG.H)。当用户的应用程序中任务数目比较少时,减少OS_LOWEST_PRIO的值可以降低μC/OS-Ⅱ对RAM(数据空间)的需求量。
任务调度(Task Scheduling) μC/OS-Ⅱ总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高,下面该哪个任务运行了的工作是由调度器(Scheduler)完成的。任务级的调度是由函数OSSched()完成的。中断级的调度是由另一个函数OSIntExt()完成的,这个函数将在以后描述。OSSched()的代码如程序清单L3.8所示。程序清单 L3.8 任务调度器(the Task Scheduler)void OSSched (void){ INT8U y; OS_ENTER_CRITICAL(); if ((OSLockNesting | OSIntNesting) == 0 { y = OSUnMapTbl[OSRdyGrp] OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); if (OSPrioHighRdy != OSPrioCur { OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy] OSCtxSwCtr++ OS_TASK_SW(); } } OS_EXIT_CRITICAL();}