开启辅助访问 切换到窄版

打印 上一主题 下一主题

任务创建TCB的内容

[复制链接]
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式




0x01

摘要
TCB的全称是任务控制块,里面存放了所有与任务运行相关的信息,任务的一切调度规则都和它有关。不同的操作系统包括WindowsLinux都包含它,只不过系统不同其具体的信息不同,系统越复杂其内容也越多。对于小型嵌入式系统,或者自己编写的系统可以根据系统的具体需要进行自己定义其内容。



0x02

引言


在介绍TCB的初始化之前,我们有必要对TCB中包含的具体信息进行了解,这样有助于大家对后面的TCB初始化的介绍的了解。


0x03

原理

这里我们采用代码加讲解嵌套进行的方式,便于对程序有一个很好的了解。
首先这里是typedef的重命名定义,将这个tcb的结构体命名为OS_TCB
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
在配置的时候如果选择了扩展任务创建的话,这里会被编译,多了用户自定义的扩展TCB存储空间并且需要告诉堆栈的栈低,堆栈大小,任务的编号。
struct os_tcb *OSTCBNext;/* Pointer to next TCB in the TCB list */
struct os_tcb *OSTCBPrev;/* Pointer to previous TCB in the TCB list*/
TCB的双向链表指针,用来指向上一个链表和下一个链表,在tcb遍历的时候就用到了这俩指针。
#if (OS_EVENT_EN) || (OS_FLAG_EN > 0)
OS_EVENT *OSTCBEventPtr;/* Pointer to event control block*/
#endif
如果选择了事件功能和标志功能,会编译一个指针变量用来指向事件或者标志的控制块,和TCB控制块类似包含很多的变量,用来标识功能。
#if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0)
OS_EVENT **OSTCBEventMultiPtr;/* Pointer to multiple event control blocks*/
#endif
如果同时开启了多事件功能,则又会多一个二级指针指向多事件的控制块。
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
void *OSTCBMsg;/* Message received from OSMboxPost() or OSQPost()*/
#endif
如果开启了队列功能或者邮箱功能,则会编译响应的指针,又来接受OSMboxPost() 或者 OSQPost()返回的信息。(这个指针的作用大家在后面内容的分析中将会用到)
#if (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
标志位的一些参数,讲到的时候在解释


INT16U OSTCBDly;/* Nbr ticks to delay task or, timeout waiting for event*/
任务的延时剩余时间,每次中断判断任务就是这个参数。
INT8U OSTCBStat;/* Task status */
任务的状态,是可以运行还是不可以,在timetick函数中就用来是否调度任务。
INT8U OSTCBStatPend;/* Task PEND status */
INT8U OSTCBPrio;/* Task priority (0 == highest) */
这两个参数一个用来表明当前的任务的状态,挂起的原因,在timetick中也用来判断任务的挂起原因。另外一个参数是优先级。
INT8U OSTCBX;/* Bit position in group corresponding to task priority*/
INT8U OSTCBY;/* Index into ready table corresponding to task priority*/
则两个参数在之前文章讲过,是优先级的分解标志,用来快速查找最高优先级,标识任务的位置,详细见前面的讲解。
#if OS_LOWEST_PRIO  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*/
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_SIZE > 1
INT8U OSTCBTaskName[OS_TASK_NAME_SIZE];
#endif
如果配置了允许设置任务的名称,这个参数就用来存储任务的名称,其实就是一个字符串数组。
} OS_TCB;


0x04

结论

以上就是TCB的具体内容,大家仔细体味各个参数的意义,在任务的运行中主要围绕这个结构体进行的,它其实就是任务的具体调度信息,任务所有的活动都需要通过这个结构来判断。也可以通过自己增加内容,设计更适合自己的操作系统调度表。


Change

你的努力
我的付出

如有任何疑问请后台回复

或添加作者Waiting_B_H





欢迎扫码
关注多一点热情多一分



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表