您的位置:首页 > 其它

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

2017-02-16 18:11 1246 查看
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书籍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: