多语言展示
当前在线:1076今日阅读:26今日分享:39

实时操作系统UCOS-II之内核结构(下)

接下来给出μC/OS-Ⅱ的主要结构概貌。读者将学习以下一些内容; μC/OS-Ⅱ是怎样处理临界段代码的; 什么是任务,怎样把用户的任务交给μC/OS-Ⅱ; 任务是怎样调度的; 应用程序CPU的利用率是多少,μC/OS-Ⅱ是怎样知道的; 怎样写中断服务子程序; 什么是时钟节拍,μC/OS-Ⅱ是怎样处理时钟节拍的; μC/OS-Ⅱ是怎样初始化的,以及 怎样启动多任务;本章还描述以下函数,这些服务于应用程序: OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL(), OSInit(), OSStart(), OSIntEnter() 和 OSIntExit(), OSSchedLock() 和 OSSchedUnlock(), 以及 OSVersion().
工具/原料
1

电脑

2

μC/OS-Ⅱ源代码

方法/步骤
1

任务控制块(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;

2

就绪表(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(数据空间)的需求量。

3

任务调度(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();}

推荐信息