第一章 任务管理

 

 

一、系统任务

UCOSIII默认有5个系统任务:

    1、空闲任务:UCOSIII创建的第一个任务,UCOSIII必须创建的任务,此任务有UCOSIII自动创建,不需要用户手动创建。

2、时钟节拍任务:此任务也是必须创建的任务。遍历所有在等待延时结束或指定时间内等待某个内核对象的任务,及遍历节拍列表。

   ① 插入节拍列表:

      dly 为要延时或等待的时间;

      MatchValue = OSTickCtr +dly

      节拍列表下标 = MatchValue %表格长度

该表是一个环形表,取模运算时一表格长度为模,将任务插入节拍列表中,在同一下标下按照延时或等待的时间长短排序。

   ② 每个节拍中断都会给此任务一个信号让其执行,通过对OSTickCtr求模(同上),找到对应的位置,与.TickCtrMatch比较是否相同,若相同就把相应的OS_TCB从时钟列表中删除,如果是等待延时,会把它放入就绪列表中;如果是等待某一事件,还需要将其从等待列表中删除;接着继续一本下标的下一个任务控制块比较。若不同则结束返回函数。

  

    3、统计任务:可选任务,用来统计CPU使用率和各个任务的堆栈使用量。此任务是可选任务,由宏OS_CFG_STAT_TASK_EN控制是否使用此任务。可以统计CPU利用率

    4、定时任务:用来向用户提供定时服务,也是可选任务,由宏OS_CFG_TMR_EN控制是否使用此任务。计时减到零会调用回调函数进行一系列操作。

5、中断服务管理任务:可选任务,由宏OS_CFG_ISR_POST_DEFERRED_EN控制是否使用此任务。当ISR调用UCOS_III中的“post”函数,要发送数据的副本和发送的目的地都会存入一个特别的缓冲队列中,当ISR执行完毕后,任务切换到中断服务管理任务,该任务会把存放的信息重发给相应的任务。做额外的这一步可以减少中断关闭的时间;否则,在ISR中还需要把任务从等待列表中删除,并把任务放在就绪表中,以及一些耗时的操作。

 

二、任务状态

   从用户的角度看,UCOSIII的任务一共有5种状态:

    1、休眠态:任务已经在CPU的flash中了,但是还不受UCOSIII管理。当任务被创建后会接受ucosiii的管理,当不再需要ucosiii的管理时将自身删除(调用函数OSTaskDel()),并没有删除此任务代码,而是使该任务无法获得CPU的使用权。

    2、就绪态:系统为任务分配了任务控制块,并且任务已经在就绪表中登记,这时这个任务就具有了运行的条件,此时任务的状态就是就绪态。

    3、运行态:任务获得CPU的使用权,正在运行。

    4、等待态:正在运行的任务需要等待一段时间,或者等待某个事件,这个任务就进入了等待态,此时系统就会把CPU使用权转交给别的任务。当等待事件发生时,就会被放入就绪列表中,进入就绪态。

    5、中断服务态:当发送中断,当前正在运行的任务会被挂起,CPU转而去执行中断服务函数,此时任务的任务状态叫做中断服务态。一般来说,ISR只是通知任务某个事件已经发生,而事件的处理则交给任务处理。ISR应当尽可能短,中断处理的大部分工作应当在UCOS_III可管理的任务级来做。ISR仅允许调用与Post()相关的这一类函数。

三、之间转换

  

1、任务在调用延时函数时,会将自身挂起,延时等待一段时间结束后会返回就绪态。

2、一个任务在等待一个事件的发生,如果没有时间限制会一直等下去,直到事件发生或等待的事件被删除,或者其他决定任务中止该等待过程;

3、一个任务在指定的一段时间内等待一个事件的发生,如果在这段时间内事件未发生就会进入就绪态且该任务会被通知等待超时。另外如果事件发生或等待的事件被删除,或者其他决定任务中止该等待过程,该等待过程结束。

四、任务控制块

  (嵌入式实时操作系统UCOSIII  P64)

struct os_tqcb {

    CPU_STK *StkPtr; //指针变量,指向自身堆栈的栈顶,便于汇编代码访问

   void      *ExtPtr;//指向用户可定义的数据区,根据需要扩展TCB,如保存浮点运算器的运行环境。

    CPU_STK  *StkLimitPtr;//堆栈中的某个位置,设置堆栈眼神的限制位置,方便溢出检测

 

   OS_TCB   *NextPtr;                         

   OS_TCB   *PrevPtr;//任务就绪列表中双向链表的前后指针

   OS_TCB   *TickNextPtr;//

   OS_TCB   *TickPrevPtr;//正在延时或在指定时间内等待某个时间的任务的OS_TCB构成双向链表

   OS_TICK_SPOKE  *TickSpokePtr;//指的是该任务挂在时钟节拍的拿一根辐条上????

   CPU_CHAR      *NamePtr;//任务的名字                    

   CPU_STK        *StkBasePtr;//指向任务堆栈的基地址。永远是&MyTaskStk[0];

   OS_TASK_PTR    TaskEntryAddr;//任务代码的入口地址

   void            *TaskEntryArg;//包含了创建时传递给任务的参数的数值,p_arg值

 

   OS_PEND_DATA  *PendDataTblPtr; //UCOSIII允许任务挂在任意数目的信号量或消息队列上,它指向一个表,包含了任务等待的所有事件的信息

OS_STATE       PendOn; /* 表示任务正在等待的事件的类型

必须是以下值:

OS_TASK_PEND_ON_NOTHING //Pending on nothing

OS_TASK_PEND_ON_FLAG     //Pending on event flag group  

OS_TASK_PEND_ON_TASK_Q    // Pending on message to be sent to task        

OS_TASK_PEND_ON_MULTI    //Pendingon multiple semaphores and/or queues 

OS_TASK_PEND_ON_MUTEX   //Pendingon mutual exclusion semaphore

OS_TASK_PEND_ON_Q        //Pending on queue

OS_TASK_PEND_ON_SEM     //Pending on semaphore                              

OS_TASK_PEND_ON_TASK_SEM   //Pending on signal  to be sent to task             

*/ 

   OS_STATUS      PendStatus;//表示等待的结果

 

   OS_STATE             TaskState;                        

   OS_PRIO              Prio;                            

   CPU_STK_SIZE         StkSize;                          

   OS_OPT               Opt;                              

 

   OS_OBJ_QTY          PendDataTblEntries;                

  

   CPU_TS               TS;                           

 

   OS_SEM_CTR           SemCtr;                          

 

                                                     

   OS_TICK             TickCtrPrev;                  

    OS_TICK              TickCtrMatch;                 

   OS_TICK             TickRemain;                     

                                                     

   OS_TICK              TimeQuanta;

   OS_TICK             TimeQuantaCtr;

 

#if OS_MSG_EN > 0u

   void                *MsgPtr;                        

   OS_MSG_SIZE          MsgSize;

#endif

 

#if OS_CFG_TASK_Q_EN > 0u

   OS_MSG_Q             MsgQ;                          

#if OS_CFG_TASK_PROFILE_EN > 0u

   CPU_TS               MsgQPendTime;                    

   CPU_TS              MsgQPendTimeMax;               

#endif

#endif

 

#if OS_CFG_TASK_REG_TBL_SIZE > 0u

   OS_REG              RegTbl[OS_CFG_TASK_REG_TBL_SIZE];

#endif

 

#if OS_CFG_FLAG_EN > 0u

   OS_FLAGS             FlagsPend;                       

   OS_FLAGS            FlagsRdy;                      

   OS_OPT              FlagsOpt;                        

#endif

 

#if OS_CFG_TASK_SUSPEND_EN > 0u

   OS_NESTING_CTR      SuspendCtr;                        

#endif

 

#if OS_CFG_TASK_PROFILE_EN > 0u

   OS_CPU_USAGE        CPUUsage;                         

   OS_CPU_USAGE        CPUUsageMax;                    

   OS_CTX_SW_CTR       CtxSwCtr;                        

   CPU_TS              CyclesDelta;                     

   CPU_TS              CyclesStart;                   

   OS_CYCLES           CyclesTotal;           

   OS_CYCLES           CyclesTotalPrev;                  

 

   CPU_TS               SemPendTime;                   

   CPU_TS              SemPendTimeMax;                

#endif

 

#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u

   CPU_STK_SIZE         StkUsed;                       

   CPU_STK_SIZE         StkFree;                      

#endif

 

#ifdef CPU_CFG_INT_DIS_MEAS_EN

   CPU_TS              IntDisTimeMax;                

#endif

#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u

   CPU_TS              SchedLockTimeMax;                

#endif

 

#if OS_CFG_DBG_EN > 0u

   OS_TCB              *DbgPrevPtr;

   OS_TCB              *DbgNextPtr;

   CPU_CHAR            *DbgNamePtr;

#endif

};

 

我所存在的疑惑1、SemCtr表示意义  2、MsgQ表示意义 有清楚的请告知 谢谢!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值