uCOS-II整理之任务

来源:互联网 发布:依云软件破解 编辑:程序博客网 时间:2024/05/22 03:52

uCOS任务
1、ucos的任务组成
任务程序代码(函数)、任务堆栈、任务控制块,如图1-1,ucos用任务控制块对任务进行管理,如图1-2。
这里写图片描述
图1-1
这里写图片描述
图1-2
2、任务的状态
任务的状态
说明
睡眠状态 :任务只是一代码的形式驻留在程序空间(ROM或者RAM)还没有交给操作系统管理是的状态。简单点说,任务在没有被配备任务控制块或被剥夺了任务控制块的状态
就绪状态 :如果任务被配备了任务控制块且在任务就绪表中进行了登记,则任务就具备了运行的充分条件,这是任务的状态叫做就绪状态
运行状态 :处于就绪状态的任务如果经调度器判断获得了CPU的使用权,则任务进入运行状态
等待状态 :正在运行的任务,需要等待一段时间或者需要等待一个事件发生再运行时,该任务会把CPU的使用权让给其他任务而进入等待状态
中断服务状态 :一个正在运行的任务一旦响应中断申请就会中止运行而去执行中断服务函数,这是任务的状态叫做中断服务状态。

3、空闲任务
为了使CPU在没有用户任务可执行时有事可做,ucos提供了一个叫做空闲任务OSTaskIdle()的系统任务。
一个应用程序必须有一个空闲任务,而且这个任务不能通过程序来删除。
空闲任务的优先级位最低优先级(LOWEST)
4、统计任务
该任务每秒钟计算一次CPU在单位时间内被使用的时间,并把计算结果以百分比的形式存放在OSCPUsage中(相当于CPU的使用率)。
统计任务的优先级为第二低优先级(LOWEST-1)
若要使用统计任务,则把OS_CFG.H中的常数OS_TASK_STAT_EN设置为1
5、任务的优先级
当多个任务需要运行时,操作系统必须选择一个来运行(因为只有一个CPU)ucos采用按优先级抢占式规则,每个任务按照重要性分配唯一的优先级别,高优先级别先运行(数字越小,优先级别越高)。
在系统配置文件OS_CFG.H中定义了用来表示最低优先级的常数OSLOWEST_PRIO。(系统把LOWEST_PRIO自动赋给空闲任务,如果使用了统计任务,则LOWEST_PRIO-1赋给统计任务。)
由于每个任务都具有唯一的优先级,因此这个优先级也是任务在系统中的标识。
6、任务堆栈
堆栈:存储器中按数据”后进先出(LIFO)”的原则组织的连续存储空。
每个任务都有自己的额堆栈。
任务控制块中都含有一个指向该任务堆栈的指针。
堆栈的数据类型:OS_STK(typedef unsigned int OS_STK)
注意:堆栈的增长方向,向上增长:MyTaskStk[0],向下增长:MyTaskStk[MyTaskStk-1]
在OS_CFG.H中定义了常数OS_STK_GROWTH作为选择开关,以适应不同的堆栈增长方式。
这里写图片描述
7、任务控制块(OS_TCB)
结构:
这里写图片描述
这里写图片描述
其中的成员OSTABStat用来存放任务的当前状态。
这里写图片描述
8、任务控制块链表(OSTCBTbl[ ])
UCOS有两条任务控制块链表:一条空任务块链表和一条任务快链表
当系统初始化时先建立一条空任务控制块链表(OSTCBTbl[ ]),当应用程序调用OSTaskCreate()创建任务时,系统会将空任务控制块链表头指针OSTCBFreeList指向的任务控制块分配给该任务,在给任务控制块的成员赋值后,就按任务控制块链表的头指针OSTCBList将其加入到任务控制块链表中,OSTCBFreeList指向空任务控制块链表的下一个节点。过程如下图所示。
这里写图片描述
这里写图片描述
为了加快对任务控制块的访问速度,UCOS在uCOS_II.H中定义了一个OS_TCB类型的OSPrioTbl[ ]数组,该数组一任务优先级为顺序在各个元素中存放了指向各个任务控制块的指针,这样在访问时就不用遍历控制块链表了,OSTCBPrioTbl[ ]与链表中的控制块之间的关系如上图所示。
删除一个任务,就是把任务块从链表中删除,并把它归还给空任务块控制链表。
9、任务就绪表
如下图所示为一个最多可以记录32个任务就绪状态的任务就绪表,实际上就是一个INT8U类型的数组OSRdyTbl[ ],每一个二进制位对应一个任务的就绪状态。
这里写图片描述
每个元素(8个位也就是对应8个任务)构成一个任务组,为了便于对就绪表的查找,uCOS定义了INT8U类型的一个变量OSRdyGrp,并使该变量的每一个位对应OSRdyTbl[ ]的一个任务组,如果任务组中有任务就绪,则OSRdyGrp里把该位置为1,否则为0.
这里写图片描述
任务的优先级别与OSRdyGrp各数据位及数组元素中各数据位的关系
这里写图片描述
10、对任务就绪表的操作
A)、登记
当某个任务处于就绪状态时,系统将该任务在任务登记在任务就绪表中,对应代码:
这里写图片描述
B)、注销
当某个任务需要脱离就绪状态时系统在就绪表中将该任务的对应位置0,对应代码:
这里写图片描述
C)、最高优先级就绪任务的查找(由任务调度器来操作)
UCOS系统是一个实时操作系统,对于任何操作都必须具有时间上的承诺,若用简单的循环查表,时间不是固定的,所以系统采用了另一种方法来查询最高优先级,对应代码:
这里写图片描述

这里写图片描述
其中,OSUnMapTbl[ ]是一张编码表,专门用于计算就绪任务中的最高优先级。

11、任务调度
在uCOS中任务调度由任务调度器完成
任务调度器主要负责两项工作:一是在任务就绪表中查找具有最高优先级的就绪任务,二是进行任务切换。
两种调度器:任务级调度器(由OSSched()实现),中断级调度器(在中断中进行任务调度,由OSIntExt()实现)
调度器任务切换分为两步:获取待运行任务的TCB指针和断点数据的切换
A)、获取待运行任务的TCB指针
操作系统是用任务控制块来管理任务的,所以任务切换工作需要获得待运行任务控制块指针和当前运行任务的控制块指针。
任务调度时会先判断调度器是否上锁,为了记录调度器被锁与解锁的情况,定义了一个变量OSLockNesting,上一次锁加1,解锁一次减1。对应代码:
这里写图片描述
这里写图片描述
获取待运行任务的TCB指针流程图
这里写图片描述
B)、任务切换宏OS_TASK_SW()
任务被终止时叫做断点,把当时存放在CPU中的内容叫做断点数据,那么任务恢复运行时,必须将断点数据作为初始数据,因此,必须在断点处将断点数据保存到堆栈中;而重新运行时,吧堆栈中的数据恢复到CPU中。保护断点数据的动作如下图所示:
这里写图片描述
改变CPU的SP指针指向不同的任务,就实现了任务的切换
为防止被中止任务堆栈指针的丢失,被中止任务在保存断点时,要把当时CPU的SP值保存到该任务控制块成员OSTCBStkPtr中。

OSCtxSw()的工作:
A)把被中止任务的断点指针保存到任务堆栈中
B)把CPU通用寄存器的内容保存到任务堆栈中
C)把被中止任务的任务堆栈指针当前值保存到该任务的任务控制块的OSTBStkPtr中(SP指针)
D)获得待运行任务的任务控制块
E)是CPU通过任务控制块获得待运行任务的任务堆栈指针
F)把待运行任务堆栈中通用寄存器的内容恢复到CPU的通用寄存器中
G)使CPU获得待运行任务的断点指针(该指针是待运行任务在上一次被调度器中止运行时保留在任务堆栈中的)

12、任务创建
用OSTaskCreate()创建任务
用OSTaskCreateExt()创建任务
13、挂起任务
INT8U OSTaskSuspend(INT8U prio)
函数OSTaskSuspend()流程图
这里写图片描述
14、恢复任务
INT8U OSTaskResume(INT8U prio)
流程图如下所示:
这里写图片描述
由图可知,任务恢复函数在判断任务确实是一个已存在的挂起任务,同时又不是一个等待任务时,就清除任务控制块成员OSTCBStat中挂起记录并使任务就绪,最后调用调度器OSSched()进行任务调度,并返回函数调用成功信息。

15、任务删除(把该任务置于睡眠状态)
具体做法:吧被删除任务的任务控制块从任务控制块链表中删除并还给空任务控制块链表,在任务就绪表中将该任务就绪状态置0
相关函数:INT8U OSTaskDel(INT8U prio),若要删除任务自己,则输入参数位OS_PRIO_SELF
删除一个占用资源的任务要谨慎,具体做饭是:提出删除任务请求的任务只负责提出删除任务请求,而删除工作则由被删除任务自己来完成。
提出任务删除请求函数:OSTaskDelReq(INT8U prio)
任务提出删除请求和被删除任务读取删除请求流程图:
这里写图片描述
提出删除任务请求的任务和被删除任务通过OSTaskDelReq()函数进行通信。
16、uCOS的初始化
系统调用OSInit(),对uCOS自身进行初始化
OSInit()对所有的全局变量和数据结构进行初始化,同时创建空闲任务OSTaskIdle和统计任务(常数OS_TASK_STAT_EN=1)
对数据结构初始化时,主要创建包括空任务控制块链表在内的5个空数据缓冲区,建立OSTCBPrioTbl[OS_LOWEST_PRIO+1],初始化后,系统数据结构如图所示:
这里写图片描述
初始化之后各全局变量的情况如下图:
这里写图片描述
这里写图片描述
17、uCOS的启动
调用函数OSStart()启动系统,前提条件是调用该函数时至少已经创建了一个用户任务。
启动系统后的数据结构如图所示:
这里写图片描述
系统启动后全局变量如下图所示:
这里写图片描述

0 0
原创粉丝点击