uC/OS-ii内核理解(四)TCB任务控制块

TCB任务控制块:用来记录任务的堆栈指针、任务当前状态、任务的优先级等一些与任务属性相关的数据结构表。任务控制块相当于任务的 “身份证”,TCB记录着任务的重要信息。

对于系统内核而言,各个任务就是通过任务控制块链接成一个表。因此,任务控制块在任务中占据重要的地位。

static  void  OS_InitTCBList (void)
{
    INT8U    ix;
    INT8U    ix_next;
    OS_TCB  *ptcb1;
    OS_TCB  *ptcb2;




    OS_MemClr((INT8U *)&OSTCBTbl[0],     sizeof(OSTCBTbl));      /* Clear all the TCBs清除所有TCB任务控制块*/
    OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl));  /* Clear the priority table清除优先级表*/
    for (ix = 0u; ix < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1u); ix++) {    /* Init. list of free TCBs初始化空TCBs列表*/
        ix_next =  ix + 1u;
        ptcb1   = &OSTCBTbl[ix];
        ptcb2   = &OSTCBTbl[ix_next];
        ptcb1->OSTCBNext = ptcb2;
#if OS_TASK_NAME_EN > 0u
        ptcb1->OSTCBTaskName = (INT8U *)(void *)"?";             /* Unknown name 未知TCB名称*/
#endif
    }
    ptcb1                   = &OSTCBTbl[ix];
    ptcb1->OSTCBNext        = (OS_TCB *)0;                       /* Last OS_TCB最后OS_TCB指向的"空"*/
#if OS_TASK_NAME_EN > 0u
    ptcb1->OSTCBTaskName    = (INT8U *)(void *)"?";              /* Unknown name 未知TCB名称*/
#endif
    OSTCBList               = (OS_TCB *)0;                       /* TCB lists initializations初始化TCB链表*/
    OSTCBFreeList           = &OSTCBTbl[0];
}

从函数中看到OS_TCB是一个数据类型,在第一条执行语句中可以看到"OSTCBTbl"这个TCB表,下面还有OSTCBPrioTbl等等关于TCB数据类型的变量。

从而可以看出该函数体里面的内容全是关于OS_TCB类型的。


跟踪代码可以看到OS_TCB类型的变量定义在ucos_ii.h中,其实这些变量是控制整个系统任务的一些全局TCB。

OS_EXT  OS_TCB           *OSTCBCur;                        /* Pointer to currently running TCB指向当前运行的TCB指针*/
OS_EXT  OS_TCB           *OSTCBFreeList;                   /* Pointer to list of free TCBs 空闲指针列表(指向OSTCBTb[])*/
OS_EXT  OS_TCB           *OSTCBHighRdy;                    /* Pointer to highest priority TCB R-to-R指向最高优先级的TCB指针*/
OS_EXT  OS_TCB           *OSTCBList;                       /* Pointer to doubly linked list of TCBs指向双向链表的TCB指针*/
OS_EXT  OS_TCB           *OSTCBPrioTbl[OS_LOWEST_PRIO + 1u];    /* Table of pointers to created TCBsTCB优先级表(指向创建的TCB)*/
OS_EXT  OS_TCB            OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS];   /* Table of TCBs TCB列表*/

从变量后面的注释可以知道关于任务的切换需要修改多少变量(指针)。


3、OS_TCB数据结构体

typedef struct os_tcb {
    OS_STK          *OSTCBStkPtr;           /* Pointer to current top of stack指向当前栈顶指针*/


#if OS_TASK_CREATE_EXT_EN > 0u /*如果使用了创建任务的扩展版本*/
    void            *OSTCBExtPtr;           /* Pointer to user definable data for TCB extension指向任务定义的TCB(扩展指针) */
    OS_STK          *OSTCBStkBottom;        /* Pointer to bottom of stack指向栈底的指针*/
    INT32U           OSTCBStkSize;          /* Size of task stack (in number of stack elements)任务堆栈容量*/
    INT16U           OSTCBOpt;              /* Task options as passed by OSTaskCreateExt()任务选项*/
    INT16U           OSTCBId;               /* Task ID (0..65535)任务ID                                   */
#endif


    struct os_tcb   *OSTCBNext;             /* Pointer to next     TCB in the TCB list指向(TCB链表中)下一个TCB指针*/
    struct os_tcb   *OSTCBPrev;             /* Pointer to previous TCB in the TCB list指向(TCB链表中)上一个TCB指针*/



#if (OS_EVENT_EN)
    OS_EVENT        *OSTCBEventPtr;         /* Pointer to          event control block指向事件控制块指针*/
#endif


#if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)
    OS_EVENT       **OSTCBEventMultiPtr;    /* Pointer to multiple event control blocks指向多事件控制块指针*/
#endif


#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u)
    void            *OSTCBMsg;              /* Message received from OSMboxPost() or OSQPost() 从消息邮箱或消息队列中得到的消息*/
#endif


#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
#if OS_TASK_DEL_EN > 0u
    OS_FLAG_NODE    *OSTCBFlagNode;         /* Pointer to event flag node指向事件标志节点的指针*/
#endif
    OS_FLAGS         OSTCBFlagsRdy;         /* Event flags that made task ready to run准备运行的事件标志任务*/
#endif


    INT32U           OSTCBDly;              /* Nbr ticks to delay task or, timeout waiting for event任务延时滴答或超时等待*/
    INT8U            OSTCBStat;             /* Task      status 任务状态                          */
    INT8U            OSTCBStatPend;         /* Task PEND status 任务悬挂状态                            */
    INT8U            OSTCBPrio;             /* Task priority (0 == highest)任务优先级                   */
/*以下4句注释为优先级<64时,>64时;采用高低4位*/
    INT8U            OSTCBX;                /* Bit position in group  corresponding to task priority优先级低3位对应的数值,即=prio&0x07*/
    INT8U            OSTCBY;                /* Index into ready table corresponding to task priority优先级高3位第一档数值,即=prio>>3*/
    OS_PRIO          OSTCBBitX;             /* Bit mask to access bit position in ready table对应就绪表组的值OSRdyTbl[OSTCBY] |= OSTCBBitX*/
    OS_PRIO          OSTCBBitY;             /* Bit mask to access bit position in ready group就绪表组OSRdyGrp |= OSTCBBitY(即上面对应的组)*/



#if OS_TASK_DEL_EN > 0u /*用于表示十分删除该任务 选通开关*/
    INT8U            OSTCBDelReq;           /* Indicates whether a task needs to delete itself         */
#endif


#if OS_TASK_PROFILE_EN > 0u /*以下是OS_TCB性能分析相关参数 选通开关*/
    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;

红色部分表示OS_TCB结构体中重要的几个参数。

1.三个重要的OS_TCB参数

OS_STK          *OSTCBStkPtr;           /* Pointer to current top of stack指向当前栈顶指针*/

 struct os_tcb   *OSTCBNext;             /* Pointer to next     TCB in the TCB list指向(TCB链表中)下一个TCB指针*/
  struct os_tcb   *OSTCBPrev;             /* Pointer to previous TCB in the TCB list指向(TCB链表中)上一个TCB指针*/

这三个参数结合在一起就构成一个链表,实质就是将各个TCB构成一个关联的表,利用指针将一个个TCB关联起来。

指向上一个TCB的指针、指向当前TCB的指针、指向下一个TCB指针。


2.任务运行时重要的OS_TCB参数

后面红色部分参数是任务运行时重要的参数。

  INT32U           OSTCBDly;              /* Nbr ticks to delay task or, timeout waiting for event任务延时滴答或超时等待*/

OSTimeDly就是将该任务延时(任务挂起)多少个滴答,其中重要的一个参数就是"OSTCBDly",这个参数传递的信息就是延时。

    INT8U            OSTCBStat;             /* Task      status 任务状态                          */

一个标志,标识任务处于什么状态。包括运行、就绪、挂起等,具体见ucos_ii.h第101行"TASK STATUS"的宏定义。


    INT8U            OSTCBStatPend;         /* Task PEND status 任务悬挂状态                            */

标识任务处于什么状态,主要包括三个状态:OS_STAT_PEND_OK、OS_STAT_PEND_TO和OS_STAT_PEND_ABORT。

详见ucos_ii.h第117行"TASK PEND STATUS"的宏定义。


    INT8U            OSTCBPrio;             /* Task priority (0 == highest)任务优先级                   */

任务优先级值越小,其优先级越高 故空闲任务优先级最低。


优先级计算参数

/*以下4句注释为优先级<64时,>64时;采用高低4位*/
    INT8U            OSTCBX;                /* Bit position in group  corresponding to task priority优先级低3位对应的数值,即=prio&0x07*/
    INT8U            OSTCBY;                /* Index into ready table corresponding to task priority优先级高3位第一档数值,即=prio>>3*/
    OS_PRIO          OSTCBBitX;             /* Bit mask to access bit position in ready table对应就绪表组的值OSRdyTbl[OSTCBY] |= OSTCBBitX*/
    OS_PRIO          OSTCBBitY;             /* Bit mask to access bit position in ready group就绪表组OSRdyGrp |= OSTCBBitY(即上面对应的组)*/

具体计算思路详见ucos_ii书籍。




  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值