任务调度机制

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ucos:uc/os 任务调度机制

疯狂代码 / ĵ:

http://NetworkProgramming/Article33556.html

uc/os 任务调度机制

by zhang9733 from /gd/dzbbs/

内核核心任务是任务调度机制为了对uc/os进行分析我们从任务调度开始在uc/os中个任务通常是个无限循环具有如下结构后面我将解释为什么会有这种结构从下面结构可以看出个任务就像其他c样;而且既然任务是个无限循环我们可以想象到它定不会返回任何数据所以返回类型应该定义为void

------------------------------------------------------------

void mytask(void *pdata)

{

for (;;) {

do something;

waiting;

do something;

}

}

uc/os可以管理64个任务但目前版本系统占用了两个任务还保留了其他六个任务故用户可以使用56个任务每个任务必须赋予定优先级优先级数越高优先级越低所以0级优先级任务有最高优先级通过在os_cfg.h文件中定义宏os_lowest_prio可以决定系统任务个数系统目前占用两个任务为空闲任务idle task和统计任务stat task当没有其他任务进入就绪状态时空闲任务投入运行空闲任务什么也不做只是简单将计数器加1这个计数器可以用来统计cpu利用率

uc/os下每个任务可以有如下五种状态

休眠态(dormant):指任务驻留在空间中还没有交给内核管理把任务交给内核是通过ostaskcreate( )或ostaskcreatext( )实现

就绪(ready):当任务旦建立这个任务就处于就绪态准备运行任务可以动态被另个建立也可以在系统运行开始之前建立通过ostaskdel( )使任务返回到休眠态就绪态任务都放在就绪列表中在任务调度时指针ostcbhighrdy指向优先级最高就绪任务也就是立刻就要运行任务

运行(running):准备就绪最高优先级任务获得cpu控制权从而处于运行态指针ostcbcur指向正在运行任务

等待或挂起(pending):正在运行任务由于延时ostimedly( )或等待事件信号量来临而将自身挂起因而处于等待或挂起态等待某事件而被挂起任务注册在该事件等待列表中

中断态(errupt):正在运行任务可以被中断除非是该任务将中断关闭被中断任务进入中断服务(isr)如果中断服务使个更高优先级任务准备就绪这中断服务结束后则更高优先级任务开始运行

任务被创建后其状态用8位字节变量ostcbstat表示目前只用了低四位如下所示(图4.1)如果某位置为1表示任务正在等待该位表示事件;可以复合使用这些标志表示任务在同时等待多个事件发生;如果所有位均为0表示任务处于就绪状态旦符合条件(优先级最高)即可投入运行

uc/os下任务状态转移如下(图4.2)所示每个任务在被创建时候个称为任务控制块(task control blocks)数据结构将被赋值

内核在化时候将所有可用任务控制块通过指针*ostcbnext和*ostcbprev连成个可用任务双向链表并将指针ostcbfreelist指向第个tcb以后每当个任务创建时就根据ostcbfreelist从可用任务双向链表获取个tcb同时将ostcbfreelist指向下个tcb如图4.3所示

uc/os是剥夺型实时多任务内核优先级最高任务旦准备就绪则拥有cpu所有权开始投入运行uc/os中不支持时间片轮转法每个任务优先级要求不样且是唯所以任务调度工作就是:查找准备就绪最高优先级任务并进行上下文切换ossched(void)进行任务调度其结构如下(4.2)

如果某个任务在某段代码执行期间不能被其他任务所抢占可以osschedlock( )来给调度器上锁以禁止调度之后再osschedunlock( )开锁允许调度例如低优先级任务要发给其他任务邮箱、消息队列时用户不希望高优先级任务还没有得到消息就取得了cpu使用权就可以使用osschedlock( )

4.2 任务调度原理

------------------------------------------------------------

如前所述uc/os是通过查表法找到准备就绪优先级最高任务下面将说明查表过程为了实现就绪任务快速查找

uc/os采用了种奇特方式既然uc/os中每个任务优先级是唯不存在相同优先级两个任务所以可以根据优先级来唯确定任务uc/os支持64个任务也就是由64个优先级0-63,二进制中可以用6位来表示然后根据高三位将64个任务分为8个准备就绪表osrdytbl[7]每组又根据低3位包含8个任务若每组有任务处于就绪态则相应比特置1;假设任务3和任务5处于就绪态则osrdytbl[0]=0x28;任务17和任务20处于就绪态则osrdytbl[2]=0x12 uc/os还定义了个8比特字节变量osrdygrp准备就绪组osrdygrp中每位表示8组任务中每组是否有准备就绪任务其相互关系见下(图4.4)

图4.4 uc/os任务查表原理

假设优先级为12任务进入就绪状态12=1 100b,则osrdytbl[1]第4位置1且osrdygrp第1位置1相应数学表达式为:

osrdygrp |=0x02;

osrdytbl[1] |=0x10;

而优先级为21任务就绪21=10 101b则osrdytbl[2]第5位置1且osrdygrp第2位置1,相应数学表达式为:

osrdygrp |=0x04;

osrdytbl[2] |=0x20;

从上面计算我们可以得到:若第n位置1则应该与2n 相或uc/os中把2nn=0-78个值 先计算好存在osmaptbl[7]中,也就是:

osmaptbl[0] =20=0x1;

osmaptbl[1] =21=0x2;

osmaptbl[7] =27=0x80;

利用osmaptbl通过任务识别号-优先级prio来设置任务在就绪组和就绪表中相应位置数学式为:

osrdygrp |=osmaptbl[prio>>3];

osrdytbl[prio>>3] |=osmaptbl[prio & 0x07];

64个优先级可用6位来表示所以高三位可用prio>>3得到低三位通过prio & 0x07获得但我直存在这样疑问

:2n运算只需通过简单移位即可获得通过查表来获得能够真正节约时间吗?

下面我们说明如何利用就绪组和就绪表来获得优先级最高就绪任务识别号即优先级数前面我们把优先级数分解为高三位和低三位从而决定任务在就绪组和就绪表中相应位置这里我们先想办法先分别求出高三位和低三位即可假设osrdygrp值为0x24=100 100b,表明osrdytbl[2]和osrdytbl[5]存在准备就绪任务根据图4.4显然

相关文档
最新文档