嵌入式实时操作系统uC/os-II(四)-任务控制块
任务控制块
uC/OS-II用来记录任务堆栈指针、任务的当前状态、任务的优先级等一些与任务管理有关的属性的表叫做任务控制块。系统通过任务控制块来感知和管理任务的,没有任务控制块的任务不能被系统承认和管理。
- 任务控制块结构的定义如下:
-
typedef struct os_tcb {
OS_STK *OSTCBStkPtr; /* Pointer to current top of stack 指向任务堆栈栈顶的指针 */
#if OS_TASK_CREATE_EXT_EN > 0
void *OSTCBExtPtr; /* Pointer to user definable data for TCB extension 指向任务控制块扩展的指针*/
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) 目前该域未被使用 */
#endif
struct os_tcb *OSTCBNext; /* Pointer to next TCB in the TCB list 指向后一个任务控制块的指针 */
struct os_tcb *OSTCBPrev; /* Pointer to previous TCB in the TCB list 指向前一个任务控制块的指针 */
#if OS_EVENT_EN
OS_EVENT *OSTCBEventPtr; /* Pointer to event control block 指向事件控制块的指针 */
#endif
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
void *OSTCBMsg; /* Message received from OSMboxPost() or OSQPost() 指向传递给任务消息的指针*/
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
#if OS_TASK_DEL_EN > 0
OS_FLAG_NODE *OSTCBFlagNode; /* Pointer to event flag node */
#endif
OS_FLAGS OSTCBFlagsRdy; /* Event flags that made task ready to run */
#endif
#else
INT16U OSTCBBitX; /* Bit mask to access bit position in ready table */
INT16U OSTCBBitY; /* Bit mask to access bit position in ready group */
#endif
#if OS_TASK_DEL_EN > 0
INT8U OSTCBDelReq; /* Indicates whether a task needs to delete itself */
#endif
#if OS_TASK_PROFILE_EN > 0
INT32U OSTCBCtxSwCtr; /* Number of time the task was switched in */
NT32U 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_SIZE > 1
INT8U OSTCBTaskName[OS_TASK_NAME_SIZE];
#endif
} OS_TCB;
- 其中成员OSTCBStat用来存放任务的当前状态,该成员变量可能的值见表2-2。
-
表2-2 OSTCBStat可能的值
值
说 明
OS_STAT_RDY
表示任务处于就绪状态
OS_STAT_SEM
表示任务处于等待信号量状态
OS_STAT_MBOX
表示任务处于等待消息邮箱状态
OS_STAT_Q
表示任务处于等待消息队列状态
OS_STAT_SUPEND
表示任务处于被挂起状态
0S_STAT_METEX
表示任务处于等待互斥信号量状态
-
任务控制块链表
uC/OS-II在初始化时也要按照配置文件所设定的任务数事先定义一批空白的任务控制块,这样当程序创建一个任务需要一个任务控制块时,只要拿一个空白块填上任务的属性即可。
从图2-5中可以看到,uC/OS-II初始化时建立的空任务链表的元素一共是OS_MAX_TASKS+ON_N_SYS_TASKS个。其中配置文件OS_CFG.H中的常数OS_MAX_TASKS指明了用户任务的最大数目;而ON_N_SYS_TASKS指明了系统任务的数目。
图2-5 uC/OS-II初始化时创建一个空任务控制块链表
当应用程序调用系统函数OSTaskCreate()或OSTaskCreateExt()创建一个任务时,系统会将空任务控制块链表头指针OSTCBFreeList指向的任务控制块分配给该任务。
图2-6是在图2-5所示任务控制块链表的基础上,应用程序创建了两个用户任务并使用了两个系统任务的情况时,空任务块链表和任务块链表的结构示意图。
图2-6 uC/OS-II 任务控制块链表和OSTCBPrioTbl[]数组及OSTCBCur
uC/OS-II在uC/OS_II.H文件中还定义了一个数据类型为OS_TCB*的数组OSPrioTbl[]。该数组以任务的优先级别为顺序在各个元素里存放了指向各个任务控制块的指针,这样子在访问一个任务的任务控制块时,就可以不必遍历任务控制块链表。
uC/OS-II允许用户应用程序使用函数OSTaskDel()删除一个任务。删除一个任务,实际上就是把该任务的任务从任务控制块链表中删掉,并把它归还给空任务控制块链表。