ucos任务状态及任务控制块

时间:2021-06-22 08:01:08

一个任务被创建后,可以处于以下五种状态之一

这五种状态分别是:

1.睡眠状态    2.就绪状态      3.等待状态     4中断服务状态    5执行状态


下面简单介绍各状态的含义即各状态的切换方法

          睡眠状态:睡眠态指任务驻留在程序空间之中,还没有交给ucos管理,把任务交给ucosii是通过调用两个函数之一

OSTaskCreate或OSTaskCreateExt,当任务一旦建立,这个任务就进入就绪准备运行,任务的建立可以是在多个任务运行开始之前,也可以

是动态地被一个运行的任务建立,如果一个任务被另一个任务建立,而这个任务的优先级高于建立它的那个任务,则这个刚刚建立的任务将立即得到CPU的控制权

一个任务可以通过调用OSTaskDel返回到睡眠态,或通过调用函数让另一个任务进入睡眠态

       等待状态:正在运行的任务可以通过调用两个函数之一将自身延迟一段时间,这两个函数是OSTimeDly或OSTimeDlyHMSM(),z这个任务于是进入等待状态,等待这段时间过去,下一个优先级最高,并进入了就绪的任务立刻被赋予CPU的控制权,等待的时间过去以后,系统服务函数OSTimeTick使延迟的任务进入就绪态,正在运行的任务期待一事件的发送时也等待,手段是调用以下3个函数之一:OSSemPend().OSMboxPend(),或OSQPend.调用后任务进入等待状态,当任务因等待事件被挂起(Pend),下一个优先级最高的任务得到CPU的控制权。当事件发送了,被挂起的任务进入就绪态,事件发生的报告可能来自一个任务,也可能来自中断服务子程序

      中断服务状态:正在运行的任务是可以被中断的,触发该任务将中断关了,或者ucos将中断关了,被中断的任务进入了中断服务态ISR,响应中断时,正在执行的任务被挂起,中断服务子程序得到控制CPU的使用权,中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态,在这种情况下,从中断服务子程序返回之前,ucos要判定,被中断的任务是否还是就绪任务中优先级最高的,如果中断服务子程序使一个优先级更高的任务进入就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。



任务控制块会被初始化,任务控制块是一个数据结构,当任务的CPU使用权被剥夺时,ucosii用它来保存该任务的状态,当任务重新得到CPU

使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差继续执行,OS_TCBs全部驻留在RAM中

任务控制块的定义如下:

# if OS_TASK_CREAT_EXIT_EN>0

  typedef struct{

     INT32U OSFree;

      INT32U OSUsed;

 }OS_STK_DATA;

#endif

typedef struct os_tcb{

   OS_STK   *OSTCBStkPtr;

#if OS_TASK_CRETE_EXT_EN

   void *OSTCBExtPtr;

   OS_STK *OSTCBStkBottom;

   OS_STK *OSTCBStkBottom;

    INT32U OSTCBStkSize;

    INT16U  OSTCBOpt;

    INT16U  OSTCBld;

#endif


  typedef struct os_tcb{

   OS_STK  *OSTCBStkPtr;

 #if OS_TASK_CREATE_EXT_EN

    void *OSTCBExtPtr;

    OS_STK *OSTCBStkBottom;

   INT32U  OSTCBStkSize;

   INT16U OSTCBOpt;

    INT16U OSTCBld;

#endif

   struct os_tcb *OSTCBNext;

   struct os_tcb *OSTCBPrev;

 #if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN||OS_SEM_EN

    OS_EVENT *OSTCBEventPtr

#endif

#if (OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN

    void *OSTCBMsg;

#endif

    INT16U   OSTCBDly;

    INT8U      OSTCBStat;

    INT8U    OSTCBPrio;


    INT8U    OSTCBx;

    INT8U    OSTCBY;

   INT8U     OSTCBBitX;

   INT8U     OSTCBBitY;

#if OS_TASK_DEL_EN

     BOOLEAN  OSTCBDelReq;

#endif


}OS_TCB;


大家可以看到,任务控制是结构体数据结构。

       OSTCBStkPtr是指当前任务栈顶的指针,ucosii允许每个任务都有自己的栈,最重要的是,每个任务栈的容量可以是任意的,

有些内存要求任务栈的容量都一样,除非用户写一个复杂的接口函数来改变,这种浪费RAM,当任务需要的栈空间不同时,也得按

任务中期栈容量需求最多来分配栈空间,OSTCBStkPtr是OS_TCB数据结构中唯一的一个能用汇编原因处理的变量,把OSTCBStkPtr

放在数据结构的最前面,使得从汇编语言汇总处理这个变量较为容易。

      OSTCBExtPtr指向用户的任务控制块扩展,用户可以扩展任务控制块而不必修改ucos员代码,OSTCBExtPtr只在函数OstaskCreateExt()使用,

故使用时要将OS_TASK_CREATE_EN设为1,允许加你任务函数的扩展,用户可以建立一个暑假结构,这个数据结构包含每个任务的名字,或跟踪某个任务的指向事件

          OSTCBStkBottom指向任务可以使用的栈空间的最高地址。函数OSTaskStkChk()要用到变量OSTCBStkBottom,在运行中检验栈空间的使用情况。用户可以用它来确定任务实际需要的栈空间。这个功能只有当用户在任务建立时允许使用OSTaskCreateExt()函数时才能实现。这就要求用户将OS_TASK_CREATE_EXT_EN设为1,以便允许该功能。

      OSTCBStkSize存有栈中可容纳的指针数目而不是用自己表示栈容量总数,也就是说,如果栈中可以保存1000个如口地址,每个地址宽度是32

位,则实际栈容量是4000字节,同样是1000个入口地址,如果每个地址宽度是16位,则总容量只有2000字节,在函数OSStakChk中调用

OSTCBStkSize,同理 若使用该函数的话,要将OS_TASK_CREAT_EXT_EN 设为1

     OSTCBOpt把选择项传给OSTaskCreateExt,只有在用户将OS_TASK_CREATE_EXT_EN设为1时,这个变量才有效,

      OSTCBld用于存储任务的识别码,这个变量现在没有使用,留给将来扩展使用

   OSTCBNext和OSTCBPrev用于任务控制块OS_TCBs的双重连接,该链表在时钟节拍函数OSTimeTick中使用,用于刷新各个任务的延迟变量OSTCBDly,

每个任务的任务控制块OS_TCB在任务建立时候被链接到链表中,在任务删除的时候从链表中被删除,双重连接的i安表示的任一个成员都不快速插入或删除

OSTCBEvenPtr是指向事件控制块的指针。

OSTCBMsg是指向传给任务的消息的指针。

OSTCBDly当需要把任务延时若干时钟节拍时要用到这个变量,或需要把任务挂起一段事件以邓艾某事件发生,这种等待是有时限制的,在这种情况下,

这个变量保存的是任务允许等待死回家发生的最多时钟节拍,如果这个变量为0,表示任务不延时,或表示邓艾死回家发生的时间没有限制


OSTCBStat是任务的状态字,当OSTCBStat为0,任务进入就绪态,可以给OSTCBStat赋其它的值,在文件uCOS_ii中有关于这个值的描述

OSTCBPrio是任务优先级,高优先级任务OSTCBPrio值小,也就是说,这个值越小,任务的优先级越高。

 OSTCBX  OSTCBY OSTCBBitX 和OSTCBBitY用于加速任务进入就绪态的过程或进入等待时间发生状态过程,这些值在任务建立,或者是在改变任务优先级输出