μC/OS-Ⅱ源码学习(1)---多任务系统的实现(上)

快速回顾

        在之前的文章中通过多个模型来建立对多任务的概念,本文将会从源码角度解析模型的具体实现。μ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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值