阅读 26

uc/os中对任务的总体理解

原文:点击打开链接

一. 任务的基本概念\

1. 任务分三个部分 :任务控制块,任务堆栈,任务程序代码。


任务控制块:关联了任务代码的程序控制块,它记录了任务的各个属性;
任务堆栈:用来保存任务的工作环境。
任务程序代码:就是任务的执行部分。

2. 任务的状态


睡眠状态:任务在没有配备任务控制块或被剥夺了作务控制块时的状态。
就绪状态:配备了任务控制块并在任务就绪表中进行了就绪登记。
运行状态:处于就绪状态的任务如果经调试器判断获得了CPU的使用权。
等待状态:正在运行的任务,需要等待一段时间,会把CPU让出来,从而进入等待状态。
中断服务状态:正在运行的任务响应中断申请就会中止运行而去执行中断服务程序,这时的状态叫做中断服务状态。

3. 任务的优先级
最多64个任务,也就是最多有64个优先级。0~63
在配置文件OS_CFG.H中定义了一个用来表示最低优先级别的常数OS_LOWEST_PRIO,所以系统可用的优先级别为0~OS_LOWEST_PRIO。
但是一般OS_LOWEST_PRIO会自动赋给空闲任务,OS_LOWEST_PRIO - 1会自动赋给统计任务。\

二. 任务的堆栈\

为了满足任务切换和响就中断时保存CPU寄存器中的内容及任务调用其他函数时的需要。\

注意处理器所支持的堆栈增长的方向:

[cpp]  view plain  copy

  1. //向下的堆栈  
  2. OSTaskCreate(Task1, (void *) 0, &Task1_Stk[TASK_STK_SIZE - 1], TASK1_PRIO);  
  3. //向上的堆栈  
  4. OSTaskCreate(Task1, (void *) 0, &Task1_Stk[0], TASK1_PRIO);  

三. 任务控制块及其链表\

数据结构如下:\

[cpp]  view plain  copy

  1. typedef struct os_tcb {  
  2.     OS_STK        *OSTCBStkPtr;        /* Pointer to current top of stack                              */  
  3.   
  4. #if OS_TASK_CREATE_EXT_EN > 0  
  5.     void          *OSTCBExtPtr;        /* Pointer to user definable data for TCB extension             */  
  6.     OS_STK        *OSTCBStkBottom;     /* Pointer to bottom of stack                                   */  
  7.     INT32U         OSTCBStkSize;       /* Size of task stack (in number of stack elements)             */  
  8.     INT16U         OSTCBOpt;           /* Task options as passed by OSTaskCreateExt()                  */  
  9.     INT16U         OSTCBId;            /* Task ID (0..65535)                                           */  
  10. #endif  
  11.   
  12.     struct os_tcb *OSTCBNext;          /* Pointer to next     TCB in the TCB list                      */  
  13.     struct os_tcb *OSTCBPrev;          /* Pointer to previous TCB in the TCB list                      */  
  14.   
  15. #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)  
  16.     OS_EVENT      *OSTCBEventPtr;      /* Pointer to event control block                               */  
  17. #endif  
  18.   
  19. #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)  
  20.     void          *OSTCBMsg;           /* Message received from OSMboxPost() or OSQPost()              */  
  21. #endif  
  22.   
  23. #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)  
  24. #if OS_TASK_DEL_EN > 0  
  25.     OS_FLAG_NODE  *OSTCBFlagNode;      /* Pointer to event flag node                                   */  
  26. #endif      
  27.     OS_FLAGS       OSTCBFlagsRdy;      /* Event flags that made task ready to run                      */  
  28. #endif  
  29.   
  30.     INT16U         OSTCBDly;           /* Nbr ticks to delay task or, timeout waiting for event        */  
  31.     INT8U          OSTCBStat;          /* Task status                                                  */  
  32.     INT8U          OSTCBPrio;          /* Task priority (0 == highest, 63 == lowest)                   */  
  33.   
  34.     INT8U          OSTCBX;             /* Bit position in group  corresponding to task priority (0..7) */  
  35.     INT8U          OSTCBY;             /* Index into ready table corresponding to task priority        */  
  36.     INT8U          OSTCBBitX;          /* Bit mask to access bit position in ready table               */  
  37.     INT8U          OSTCBBitY;          /* Bit mask to access bit position in ready group               */  
  38.   
  39. #if OS_TASK_DEL_EN > 0  
  40.     BOOLEAN        OSTCBDelReq;        /* Indicates whether a task needs to delete itself              */  
  41. #endif  
  42. } OS_TCB;  

ucos需要两个链表:\

一条空任务块链表,其中所有任务控制块还未分配给任务。由OSInit()创建。

\

一个任务块链表,其中所有任务控制块已分配给任务。由OSTaskCreate()创建。

\

创建时,系统会将空任务控制块链表头指针OSTCBFreeList指向的任务控制块分配给该任务。
图3-6是在图3-5所示的空任务控制块链表甚而上,应用程序创建了两个用户任务并使用了两个系统任务的情况。
\

四. 任务就绪表及任务调度\

1. 任务就绪表的结构
是一个位图,每一位代表一个任务,1表示就绪,0表示非就绪。\

可以看出一个元素可以表达8个任务的就绪状态。

\

还有一个变量表示哪个组个元素就绪了:

\

优先级也就绪表的位置关系:


2. 对任务就绪表的操作
登记:指的是当某个任务处于就绪状态时,把就绪表中对应的位置置1。
注销:把就绪表中对应的位置清0。
最高优先级任务的查找:从表中查找出最高优先级

3. 任务调度
调度的思想 是:近似地每时每刻让优先级最高的就绪任务处于运行状态。
具体做法是:在系统或用户任务调用系统函数及执行中断服务程序结束时来调用调度器(OS_Sched())。
调度器先在任务就绪表中查找具有最高优先级别就绪任务的代码,然后进行任务切换。\

任务切换的工作分成两步:第一步是获得待运行任务的TCB指针;第二步是进行断点数据的切换。

\

任务切换的工作是靠OSCtxSw()来完成的。

\

\

五. 任务的创建\

OSTaskCreate()
OSTaskCreateExt()\

六. 任务的挂起和恢复\


挂起任务:
INT8U OSTaskSuspend(INT8U prio);
恢复任务:
INT8U  OSTaskResume (INT8U prio);
任务的删除:
INT8U  OSTaskDel (INT8U prio);
也就是把该任务置于睡眠状态,把任务控制块链表中删除,并归还给空任务控制链表。

文章分类
代码人生
文章标签