UC/OS II任务管理(1)之任务控制块

任务状态
UCOSII任务状态一共有睡眠、就绪、阻塞、运行、以及中断挂起五种状态。
睡眠态(Dormant):任务已经在内存中装入,但是还没有进行任务运行的所需要的条件。
就绪态(Ready):是任务已经做好运行的一切准备了,就只差调度程序调度,将CPU让给运行。
阻塞态(Waiting):当任务因为需要某些资源或条件,得不到满足的时候,或者是任务需要等待一定的时间的时候,任务设置为阻塞态。知道条件满足,或者等待时间耗尽,任务再转换成就绪态。
运行态(Runing): 任务正在CPU上运行
中断挂起状态(ISR):当有中断发生的时候,CPU就会转去执行中断程序。这个时候任务被剥夺CPU的使用权,处于挂起状态。中断返回之后,如果任务还是最高优先级,就继续运行。
任务转换状态运行如下:




任务控制块
任务控制块os_tcb记录了相应的任务的状态以及信息。相当于Linux系统的PCB进程控制块。伴随着任务的产生而产生,一点随着任务的撤销而撤销。
下面解读注释一下任务os_tcb结构体,该数据结构定义在ucos_ii.h
typedef struct os_tcb {
    OS_STK          *OSTCBStkPtr;          //指向对应任务的堆栈栈顶指针,堆栈用用于存储该任务的上下文环境。


#if OS_TASK_CREATE_EXT_EN > 0u  
//#if到#endif这个部分,是在要使用的任务拓展实现更多的功能时候用到的,使用这部分需要将宏OS_TASK_CREATE_EXT_EN定义大于1,该宏定义在os_cfg.h头文件中。
    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                 */
//若是使用事件管理,该OSTCBEventPtr 指针就是指向相应事件控制块的指针。是否使用事件管理,需将宏OS_EVENT_EN定义为1,该宏定义在ucos_ii.h
#if (OS_EVENT_EN)
    OS_EVENT        *OSTCBEventPtr;         /* Pointer to          event control block                 */
#endif
//若是宏OS_EVENT_EN和OS_EVENT_MULTI_EN都定义为1,则会使用多事件,OSTCBEventMultiPtr指向多事件控制块指针,OS_EVENT_MULTI_EN在os_cfg.h中定义
#if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)
    OS_EVENT       **OSTCBEventMultiPtr;    /* Pointer to multiple event control blocks                */
#endif


若是使用了消息机制,OSTCBMsg指向消息地址。三个宏都定义在os_cfg.h头文件中
#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u)
    void            *OSTCBMsg;              /* Message received from OSMboxPost() or OSQPost()         */
#endif


事件标识,OSTCBFlagNode 指向事件标识节点,OSTCBFlagsRdy事件标志
#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;         //任务延迟的时间tick数,以及等事件的时间期限     /* Nbr ticks to delay task or, timeout waiting for event   */
    INT8U            OSTCBStat;          //任务的状态。OSTCBStat数据的8位分别表示八种不同的状态。各位表示状态如下表:  

 
    INT8U            OSTCBStatPend;   //事件任务等待标志      /* Task PEND status  */
    INT8U            OSTCBPrio;          //任务的优先级   /* Task priority (0 == highest)                            */



下面四项是用于关于优先级运算结果的存储,即在任务创建的时候运算一次,以后在任务调度的时候就不需要进行反复运算。
OSTCBX 任务优先级左移三位,OSTCBBitX任务优先级在优先级表组中的位置
OSTCBY任务的低三位,OSTCBBtiY 任务优先级在对应的任务就绪表中的位置
    INT8U            OSTCBX;                /* Bit position in group  corresponding to task priority   */
    INT8U            OSTCBY;                /* Index into ready table corresponding to task priority   */
    OS_PRIO          OSTCBBitX;             /* Bit mask to access bit position in ready table          */
    OS_PRIO          OSTCBBitY;             /* Bit mask to access bit position in ready group          */

#if OS_TASK_DEL_EN > 0u
    INT8U            OSTCBDelReq;        //任务的删除的请求标志   /* Indicates whether a task needs to delete itself         */
#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;

任务控制块实体
     任务控制块的数目的生成在ucosii.h中,为一个全局变量数组OS_TCB     OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS](ucos_ii.h);
      OS_MAX_TASKS 宏为用户任务数目,在ucosii.h当中定义,可以根据自己系统运行的任务数目来配置,最大为62(有多少任务,配置多少,否则会造成内存资源的浪费)。
     OS_N_SYS_TASKS宏为系统任务,一般为2,一个为空闲任务,一个为统计任务 。若是不需要统计任务,OS_TASK_STAT_EN宏配置为1,。则系统只有一个一个系统任务,该宏在os_cfg中定义。

     前面的的生成的任务控制块,分别会挂在 空闲链表就绪链表两个链表上。在系统初始化的时候(OSInit),所有的任务控制块都是在空闲链表中。空闲链表是单链表,而就绪链表都是双向链表。指向两个链表的全局指针变量都在ucosii.h中定义。

任务优先级指针数组
    任务优先级指针数组OS_TCB    *OSTCBPrioTbl[OS_LOWEST_PRIO + 1u](ucos_ii.h),该全局变量OS_TCB指针数组都指向下标相对应的优先级的控制块。根据优先级查找相对应的任务控制块的时候,就根据这个数组指针的下标来得到。
     

     

     
     











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值