ucos-ii的任务调度机制
1、在ucos-ii中,有这么几张表来管理任务。
A、OSTCBPrioTbl[],其结构为OS_TCB指针的数组,其元素个数为64, 每一个元素对应一个任务的优先级,ucos-ii最多可以有64个任务,所以当有任务建立的时候,其每一个元素均指向一个任务控制块(若相应的优先级,已经建立了任务的话);若相应的优先级没有建立任务,则该数组元素指向的是(OS_TCB *)0;
B、任务控制块链表,该链表的每个节点,都是OS_TCB型结构。任务控制块链表除了本身构成一个双向链表, 其还与OSTCBPrioTbl[](OSTCBPrioTbl[]存放的就是任务控制块的首地址)和任务堆栈相联系(通过OS_TCB结构的OSTCBStkPtr元素指向任务堆栈的栈顶来实现)。在新建一个任务的时候,都必须新建任务控制块置于任务控制块链表中,通过OSTCBList来实现将其放于任务控制块链表的开头即新建的任务控制块。
C、任务就绪表,为9个字节,(OSRdyGrp和OSRdyTbl[8]).
OSRdyGrp存放的优先级分组的号。若其中的有一位置1, 表明其有任务处于就绪状态,若为0表示没有任务处于就绪状态。假设OSRdyGrp的第i位为1, 则表示处于任务优先级(i-1)*8~i*8-1中,至少有一个任务的处于就绪态(其中i属于(1~8))。
OSRdyTbl[8]的每个元素为8位,每一位代表一个任务优先级。这样8*8刚好为64,所以刚好可以存放完ucos-ii的最大任务总数。在该数组中,根据每位的值为0/1来决定其对应优先级的任务是否处于就绪态。为0表示该优先级任务不处于就绪状态,为1表示处于就绪态。同时当OSRdyTbl[]有一位为1时,该位代表的优先级将OSRdyGrp中对应的为置1。
由于ucos-ii为实时系统,为了尽量缩短查找表所用的时间,其还定义了两个常数数组,一个为OSMapTbl[8]和OSUnMapTbl[256]。(我个人认为这两个数组的设计最为巧妙和最有价值),通过这两张表很方便的就可以查询是否有任务处于就绪态,处于就绪态的最高优先级是多少。并且将一个任务置于就绪状态或者进行任务的调度都需要利用这两个常数数组。
OSMapTbl[]表如图1所示:
OSUnMapTbl[]表如图2所示:
D、空任务控制块链表,用来管理空任务控制块。当新建任务时,需要从该链表获取一个OS_TCB, 并将其放于任务控制块链表中。在这过程中主要是通过两个OS_TCB指针来完成,一个是OSTCBFreelist,另一个是OSTCBList,这两个指针始终指向链表的开头。
2、任务的创建过程
通过函数OSTaskCreate()或者OSTaskCreateEXT()两个函数来创建一个任务。
A、能否创建成功取决于这么几个条件:
a) 分配给即将要创建任务的优先级是否合法,prio<63(或者为自己修改的最大任务数);
b) 分配给将要创建任务的优先级是否已经被已存任务所占用,若没有被占用,则将OSTCBPrioTbl[prio]赋值1,来占用该优先级;
c) 是否有足够的RAM来分配给任务,作为任务的私有堆栈;
d) 是否有空余的OS_TCB分配给任务,作为该任务的任务控制块;
B、任务创建完后,上面所提到的有关任务控制块的几张表的更新。
a) OSTCBPrioTbl[]表:将新创建任务的任务控制块首地址存放在相应任务优先级元素中(即OSTCBPrioTbl[prio]中)。
b) 任务控制块链表:将OSTCBList指针更新指向新建的任务控制块,另外通过OS_TCB结构中的OSTCBNext和OSTCBPrev成员,将新建任务的OS_TCB置于双向链表中。
c) 任务就绪表的更新:新建任务建完后为就绪状态,因此应该将任务优先级在任务就绪表中相应的位置1, 其实现方式通过以下两条指令实现:OSRdyGrp |=OSMapTbl[prio>>3];
OSRdyTbl[prio>>3] |=OSMapTbl[prio & 0x07];
d) 空任务控制块链表:因为新建任务必须从空任务控制块中取出,所以在取完空OS_TCB需后,要修改OSTCBFreeList指针,将其指向下一个空OS_TCB。
C) 任务新建完后,与任务相关参数的设置。
任务的OS_TCB 存放在OSTCBPrioTbl[prio]中,任务的私有堆栈信息(栈顶指针、栈底指针和堆栈大小)存放在任务的OS_TCB中。任务函数的首地址存放在任务的堆栈中。
3、任务调度
A) 任务调度发生的时间
a)系统刚启动,完成初始化和至少建立了一个任务后,通过OSStart()函数调用__OSStartHighRdy函数将OSRunning=TRUE后,通过任务切换函数OSCtxSw来启动。
b) 系统运行过程中,新建任务的时需要启动任务调度器OSSched(),进行任务调度。
c) 任务被挂起或者等待延时或者等待其他时间发生时,需要进行任务调度。
d) 任务在运行过程中,有更高优先级任务处于就绪状态时,需要进行任务的调度(通过定时器中断服务程序,查询和更新所有任务状态时发现其是否有更高优先级任务处于就绪态)。
e) 中断服务程序运行过程中(ISR中需要使用任务)或者运行完之后需要进行任务的调度。
B) 怎样找到任务并运行
第一步:通过任务调度器或其他的方式,获得任务中的最高优先级prio;
第二步:通过prio在OSTCBPrioTbl[]中查找与prio相应的任务控制块,因为OSTCBPrioTbl[prio]中存放的就是与prio对应的OS_TCB,所以很容易就知道找到该OS_TCB。
第三步:获得任务的OS_TCB后,通过任务控制块中存放的有关堆栈信息来找到任务的私有堆栈。在堆栈中,将任务私有堆栈存放的有关处理器寄存器的内容恢复,则开始运行该任务。
在这过程中,有几个地方要记住:
1) 运行任务前,应该将其优先级在任务就绪表中相应的为清零;
2) 必须保存前一任务的信息;
ucos-ii的任务调度机制的更多相关文章
- DE1-SOC开发板上搭建NIOS II处理器运行UCOS II
DE1-SOC开发板上搭建NIOS II处理器运行UCOS II 今天在DE1-SOC的开发板上搭建NIOS II软核运行了UCOS II,整个开发过程比较繁琐,稍微有一步做的不对,就会导致整个过 ...
- ucos ii 46个系统API函数解析
源: ucos ii 46个系统API函数解析
- FreeRTOS 和uCOS II的简单比较
转载:http://www.viewtool.com/bbs/forum.php?mod=viewthread&tid=114 这是两种RTOS, 现在粗略比较一下. freeRTOS比uCO ...
- FairScheduler的任务调度机制——assignTasks(续)
上一篇文章浅析了FairScheduler的assignTasks()方法,介绍了FairScheduler任务调度的原理.略过了最后一步通过JobScheduler获取Task时调用JobInPro ...
- ucos ii 百度官方介绍
μC/OS II(Micro-Controller Operating System Two)是一个可以基于ROM运行的.可裁剪的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处 ...
- Spark内核-任务调度机制
作者:十一喵先森 链接:https://juejin.im/post/5e1c414fe51d451cad4111d1 来源:掘金 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. ...
- FairScheduler的任务调度机制——assignTasks
首先需要了解FairScheduler是如何在各个Pool之间分配资源,以及每个Pool如何在Job之间分配资源的.FairScheduler的分配资源发生在update()方法中,而该方法由一个线程 ...
- spark内核篇-任务调度机制
在生产环境中,spark 部署方式一般都是 yarn-cluster 模式,本文针对该模式进行讲解,当然大体思路也适用于其他模式 基础概念 一个 spark 应用包含 job.stage.task 三 ...
- rontab踩坑(三):crontab定时任务调度机制与系统时间/时区的不一致
解决方案: 因为我们的服务器在是肯尼亚: 我么查看一下localtime 是否和 时区一致? 可以看到是一致的. 应该是是配置改动后未重启! service crond restart
随机推荐
- 02_Linux图形界面及文件系统结构介绍
一.根目录 / : 它跟Windows的C.D.E.F不同,在Linux中,所有的文件系统(光驱.U盘.硬盘)都挂载到根目录的某一个文件夹下 bin : 存放二进制可执行文件 sbin ...
- wpf图片浏览器,实现缩放平移操作图片切换等功能
wpf经常要用到控件来查看图片,尤其是高清图片,于是做了一个例子: 1.定义图片的队列,用list来存. private readonly List<string> files; 2.切换 ...
- 突然觉得前端js挺不错的
由于工作的需要,现在对前端技术有一定的要求,但是发现普遍前端技术都比较弱,遇到问题基本上没有人能帮助你解决,只好自己学习了. 从事java开发已经好久了,真的是好久了,但是水平一直还是一般吧. 从今天 ...
- Python基础篇(二)
Python最基本的数据结构是序列(sequence),序列中的每个元素被分以以0开头的唯一的一个id号. Python中有6种内建的序列:列表,元组,字符串,Unicode字符串,buffer对象和 ...
- 帝国CMS备份出现数据恢复不完整的问题
今天linux主机中毒了,把用帝国备份王备份之后,恢复了快照到刚建主机的状态: 哎,只怪当初没有勤快的去做快照啊: 重新配置好后: 开始使用帝国备份王: 数据恢复之后,打开文章,提示"附加表 ...
- SynchronousQueue 的联想
SynchronousQueue介绍 SynchronousQueue是一种阻塞队列,该队列没有任务的容量.内部实现采用了一种性能更好的无锁算法. 代码实现里的Dual Queue,其中每一个put对 ...
- javascript Map和Set
Map和Set JavaScript的默认对象表示方式{}可以视为其他语言中的Map或Dictionary的数据结构,即一组键值对. 但是JavaScript的对象有个小问题,就是键必须是字符串.但实 ...
- Linux 每日命令行
uptime 用于查看系统的负载信息. 它依次显示 当前系统时间.系统已运行时间.启用终端数量及平均负载值等信息.平均负载指的是系统在最近1分钟.5分钟.15分钟内的压力情况:负载值越低越好,尽量不要 ...
- jquery序列化serialize()方法空格变为+问题解决参考方法
$("#sendNoticeData-form").serialize();会在value中存在空格的地方转化为+符合.比如:name:tiwax aaa序列化后为tiwax+aa ...
- PHP 个人用到的琐碎代码记录
查找字符串出现次数的方法 substr_count(string,substring,[start],[length]) 函数延迟代码执行若干秒,若成功,返回 0,否则返回 false. sleep( ...