快速回顾
在之前的文章中通过多个模型来建立对多任务的概念,本文将会从源码角度解析模型的具体实现。μC/OS-Ⅱ中的多任务
https://blog.youkuaiyun.com/sherlock_cp/article/details/130077923
任务控制块
在μC/OS-Ⅱ中,任务控制块类型为OS_TCB,包含了大量的成员:
//ucos_ii.h
typedef struct os_tcb {
OS_STK *OSTCBStkPtr; //任务堆栈当前位置指针
#if OS_TASK_CREATE_EXT_EN > 0u
void *OSTCBExtPtr; //任务扩展块指针
OS_STK *OSTCBStkBottom; //任务堆栈栈底
INT32U OSTCBStkSize; //任务堆栈长度
INT16U OSTCBOpt; //选项字节
INT16U OSTCBId; //任务(0..65535)
#endif
struct os_tcb *OSTCBNext; //指向下一个任务控制块,用于形成双向链表结构
struct os_tcb *OSTCBPrev; //指向上一个任务控制块,用于形成双向链表结构
#if (OS_EVENT_EN)
OS_EVENT *OSTCBEventPtr; /* 任务等待事件指针,如发生等待,会指向对应事件 */
#endif
#if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)
OS_EVENT **OSTCBEventMultiPtr; /* 任务等待多重事件的指针 */
#endif
#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u)
/* 通常发送的消息或邮件会存放到对应的消息队列或邮箱中,但若遇到堵塞,则这些信息会到这里 */
void *OSTCBMsg;
#endif
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
#if OS_TASK_DEL_EN > 0u
OS_FLAG_NODE *OSTCBFlagNode; /* 事件标志节点 */
#endif
OS_FLAGS OSTCBFlagsRdy; /* 当前存在的事件标志位 */
#endif
INT32U OSTCBDly; //任务等待执行延时
INT8U OSTCBStat; //任务状态(就绪、pending)
INT8U OSTCBStatPend; //任务pending状态
INT8U OSTCBPrio; //任务优先级
INT8U OSTCBX; /* 任务的组内优先级 */
INT8U OSTCBY; /* 任务的优先级组 */
OS_PRIO OSTCBBitX; /* 任务的组内优先级掩码,用于快速映射和寻找 */
OS_PRIO OSTCBBitY; /* 任务优先级组掩码,用于快速映射和寻找 */
#if OS_TASK_DEL_EN > 0u
INT8U OSTCBDelReq; /* 任务删除请求标志 */
#endif
#if OS_TASK_PROFILE_EN > 0u
INT32U OSTCBCtxSwCtr; /* Number of time the task was switched in */
INT32U OSTCBCyclesTot; /* Total number of clock cycles the task has been running */
INT32U OSTCBCyclesStart; /* Snapshot of cycle counter at start of task resumption */
OS_STK *OSTCBStkBase; /* Pointer to the beginning of the task stack */
INT32U OSTCBStkUsed; /* Number of bytes used from the stack */
#endif
#if OS_TASK_NAME_EN > 0u
INT8U *OSTCBTaskName; //任务名称
#endif
#if OS_TASK_REG_TBL_SIZE > 0u //任务寄存器,可以用于存储任务执行过程中的数据
INT32U OSTCBRegTbl[OS_TASK_REG_TBL_SIZE];
#endif
} OS_TCB;
多任务系统模型
在μC/OS-Ⅱ系统创建之初,下图所展示的多任务模型就已经建立(具体逻辑回顾前文),只不过其中的任务控制块都是空白的。OSTCBFreeList链表可以理解为系统剩余的空白任务控制块,而OSTCBList链表会在每次创建任务时,从OSTCBFreeList截取一个任务控制块并填充信息装载到自身。

这里涉及到的多个重要的全局变量,都定义在ucos_ii.h文件中:
//ucos_ii.h
OS_EXT OS_TCB *OSTCBCur; //当前正在运行任务的任务控制块指针
OS_EXT OS_TCB *OSTCBFreeList; //空白任务控制块链表
OS_EXT OS_TCB *OSTCBHighRdy; //就绪的最高优先级任务控制块指针
OS_EXT OS_TCB *OSTCBList; //已注册任务的任务控制块链表
OS_EXT OS_TCB *OSTCBPrioTbl[OS_LOWEST_PRIO + 1u]; //任务优先级数组,可以快速定位对应任务控制块,+1是因为优先级0也是一个任务
OS_EXT OS_TCB OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS]; //所有任务(空白+已注册)的任务控制块数组,包含的是任务控制块实体而非指针
包括五个指针和一个数组,其中数组OSTCBTbl[]是真正包含所有任务控制块的数据实体,其它指针都是对这些实体的引用。
其中涉及的配置宏定义:
OS_N_SYS_TASKS:系统任务的数量(最多2个,空闲和统计任务),其中空闲任务必须存在,统计任务按需开启;
OS_LOWEST_PRIO:任务的最低优先级,也即空闲任务的优先级;
OS_MAX_TASKS:最大任务数量,注意该数量不包括系统任务数;
初始化多任务系统
在OSInit()函数运行时,里面有一个OS_InitTCBList()

最低0.47元/天 解锁文章
680

被折叠的 条评论
为什么被折叠?



