嵌入式操作系统_第5章 ucOS-II - 任务就绪表及任务就绪组
UCOS任务就绪表的理解
![UCOS任务就绪表的理解](https://img.taocdn.com/s3/m/5f5407a5f121dd36a32d828e.png)
ucos_ii 作为一个实时系统,最主要的任务就是为了实现任务的调度,为了实现任务的调度,使用了任务就绪表的方法来供ucos来查询(实时性)最高优先级的任务,并且切换到最高优先级任务去执行。
注意两个地方:第二任务的创建或者是其他需要任务切换过程中,就绪表就会得到更新,并供ucos服务程序os_sched()查询第一为了满足时间确定性,所以不能够使用for循环的遍历方式去遍历就绪表以找到最高优先级的任务,所以此处用了查找表的方式1、就绪表的基础系统存在多个任务(对于不同的版本任务个数不同,此处的任务个数最多不超过64个),ucos在做任务调度的时候,需要知道那些任务已经准备好可以运行,并且还要知道最高优先级的任务是哪个。
ucos使用就绪表的方式来实现这一功能。
当前的ucos总共有64个任务,将64个任务分成8组来表征,每一组中用一个Uint8类型的数据的每一位来表征8个task。
那么总共就可以表征64个任务。
ucos设定了两个变量来表征就绪表uint8OSRdyGrp;uint8OSRdyTbl[] ;如上表所示:第一列的8位组合成为OSRdyGrp的值,用来表征任务的优先级实在哪个组,置一表示有任务就绪,置0表示无任务就绪第一行的8bit组成一个OSRdyTbl[0..7]的值,OSRdyTbl[]中有8个值每一个值对应一个组的就绪任务,这个值的8bit又是对应上表的列名称例如我有一个优先级为20的任务准备就绪,并且如上表标识.那么OSRdyGrp = 0x01;OSRdyTbl[] = {0x00 , 0x00 , 0x10, 0x00 , 0x00 , 0x00, 0x00 , 0x00};任务就绪可以通过下面的操作来完成OSRdyGrp |= OSMapTbl[prio >> 3]; // prio 为一个8位的数据,假设prio为20,那么他的高三位表征了他是低2组中的某一个中断OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07]; //prio 为一个8位的数据,假设prio为20,那么他的低三位表征了他是某一组中的第4个中断OSMapTbl[] = {0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40, 0x80};//这个查找表就是要让它对应到位上查找就绪表中的最高优先级的任务:由于要满足实时系统的实时性,那么查找到最高优先级的任务就不能通过遍历64个就绪表来确定,应为那样遍历的时间是不确定的。
uC_OS-II实验指导书2015 - 2
![uC_OS-II实验指导书2015 - 2](https://img.taocdn.com/s3/m/66bca825eefdc8d376ee32af.png)
实验2任务就绪表
1实验目的
掌握任务就绪表及任务就绪组的结构及二者之间的关系,系统需要一个就绪登记表,它登记系统中所有处于就绪状态的任务,这个就绪表就是一个位图,系统中的每个任务都在这个位图中占据一个二进制位,该位的状态(1或0)就表示任务是否处于就绪状态。
为了便于对就绪表的查找,系统又定义了一个数据类型为INT8U的变量OSRdyGrp,并使该变量的每一位都对应于OSRdyTbl[]的一个任务组,如果任务组中有就绪任务,则在变量OSRdyGrp里把该任务组所对应的位置1。
理解基于优先级调度的嵌入式实时操作系统的实现策略。
2实验内容
变量定义如下:
INT8U OSRdyGrp=0;
INT8U OSRdyTbl[8]={0};
INT8U OSMapTbl[8]={1,2,4,8,16,32,64,128};
INT8U OSUnMapTbl[256]={0};
INT8U x,y,OSPrioHighRdy,prio;
(1)编程对OSUnMapTbl数组进行初始化;
(2)输入多个任务的优先级prio,修改OSRdyGrp、OSRdyTbl的值并输出;
(3)根据OSRdyGrp、OSRdyTbl的值,求最高优先级任务的优先级OSPrioHighRdy并输出;
3实验代码(要求有注释)
4实验结果(截图)
5心得体会(不少于200字)
1。
ucos-ii中就绪表查表算法及osunmaptbl表格的由来
![ucos-ii中就绪表查表算法及osunmaptbl表格的由来](https://img.taocdn.com/s3/m/fcf4481d763231126edb114a.png)
μCOS-II 中就绪表查表算法及OSUnMapTbl 表格的由来OSUnMapTbl 的由来为什么要采用这样的一个表格呢?μC/OS-II 是一个实时系统,在操作时间上它的所有操作都必须是常量,用通俗的话来说:“系统的任何操作都必须具有时间上的承诺”,而循环程序是不能达到这个要求的,所以才采取了这样的一个查表方法。
表格中的数据是如何得到的呢?其实这些数据就是0~255数据字节从低位到高位中(即从左到右)第一个被置1的位的位置。
具体过程如下:(大家可以对照源码中OSUnMapTbl 数组)…OSUnMapTbl[0] = 0…OSUnMapTbl[1] = 0…OSUnMapTbl[2] = 1…OSUnMapTbl[3] = 0…OSUnMapTbl[4] = 2…OSUnMapTbl[5] = 0…OSUnMapTbl[6] = 1…OSUnMapTbl[7] = 0…OSUnMapTbl[8] = 3……Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 0 0 0x00 没有被置1的位,故位置为0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 0 1 0x01 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 1 0 0x02 首个被置1的位置为bit1Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 1 1 0x03 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 0 0 0x04 首个被置1的位置为bit2Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 0 1 0x05 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 1 0 0x06 首个被置1的位置为bit1Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 1 1 0x07 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 1 0 0 0 0x08 首个被置1的位置为bit3…OSUnMapTbl[15] = 0…OSUnMapTbl[16] = 4…OSUnMapTbl[31] = 5…OSUnMapTbl[47] = 4…OSUnMapTbl[63] = 6………OSUnMapTbl[240] = 4………OSUnMapTbl[255] = 0快速查表过程y = OSUnMapTbl[OSRdyGrp]; // 获得优先级别的D5,D4,D3位(即先找出是哪一组) x = OSUnMapTbl[OSRdyTbl[y]]; // 获得优先级的D2,D1,D0位(再从哪一组中找出是哪一位) prio = (y<<3) + x; // 获得就绪任务的优先级别 ① 首先将就绪任务组OSRdyGrp 用来在OSUnMapTbl[]中进行查表,找出OSRdyGrp 的位中首次置1位置,确定出当前就绪表中最高优先级是哪一组任务,即优先级的D5,D4,D3位。
嵌入式操作系统uCOS2复习指南
![嵌入式操作系统uCOS2复习指南](https://img.taocdn.com/s3/m/2dbac331a5e9856a5612609e.png)
复习:第一章:实时操作系统、操作系统基本功能、任务、多任务、任务状态及相互关系、任务切换、可重入和不可重入;可剥夺和不可剥夺内核;同步与通信:同步、互斥、临界区、事件、信号量、互斥信号量、消息邮箱、消息队列;中断、时钟、内存管理。
第二章:任务管理:任务控制块TCB数据结构及各数据项意义任务控制块实体任务控制块空闲链表、就绪链表优先级指针表任务堆栈任务就绪表及就绪组及相关代码图2.16:任务状态转换图,要弄清楚任务各状态及转换条件程序2.6,2.7,2.8和2.9,获取就绪任务中的最高优先级,能给出OsRdyGrp和OsRdyTbl后,依据程序,算出最高优先级;并且说明处理时间是恒定的程序2.10、2.11、2.14、2.15、2.17、2.27、2.28、2.29、2.30、2.34分析第三章中断和时间管理中断处理流程,图3.1时钟中断服务,程序3.2,OSTIMETICK(程序2.27)任务延迟函数OSTIMEDLY作用及代码分析(程序3.4)第4章ECB数据结构事件等待组、等待表作用,与就绪组合就绪表有何联系和不同事件控制块空闲链表及ECB初始化函数(程序4.3)事件等待函数(程序4.5)将等待事件就绪(程序4.8)信号管理:OSSEMCREAT、OSSEMDEL、OSSEMPEND、OSSEMPOST4.3.9:信号量应用举例互斥信号管理:OSMutexCreat、OSMutexDEL、OSMutexPEND、OSMUtexPOST优先级反转解决优先级反转采用何种策略4.4.8:互斥信号量应用举例第5章5.1 消息邮箱:OSMBOXCREAT、DEL、PEND、POST5.1.8 例子5.2消息队列:Os_QInit,OsQCreat;POST;PEND消息队列数据结构:图5.8到5.115.2.8 例子第6章内存管理内存控制块数据结构MCB链表Os_MemInit();OsMemCreat();OsMemGet();OsMemPut()设内存区有6个块构成,依次画出4个图:内存块创建后、分配一个块后、再分配两个块后、释放第一次分配的块后的结构图。
嵌入式系统UCOS2学习
![嵌入式系统UCOS2学习](https://img.taocdn.com/s3/m/37bd0d03c4da50e2524de518964bcf84b8d52d59.png)
嵌入式系统UCOS2学习/s/blog_5f0bed160100tqnv.html20113、非空闲任务控制块双向链表ucos-II的任务状态l 睡眠态(Dormant):指任务驻留在程序空间之中,还没有交给μC/OS-Ⅱ管理。
把任务交给μC/OS-Ⅱ是通过调用下述两个函数之一:OSTaskCreate()或OSTaskCreateExt()。
一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。
l 就绪态:当任务一旦建立,这个任务就进入就绪态准备运行。
l 运行态:调用OSStart()可以启动多任务。
OSStart()函数运行进入就绪态的优先级最高的任务。
就绪的任务只有当所有优先级高于这个任务的任务转为等待状态,或者是被删除了,才能进入运行态。
l 等待状态:正在运行的任务可以通过调用两个函数之一将自身延迟一段时间,这两个函数是OSTimeDly()或OSTimeDlyHMSM()。
这个任务于是进入等待状态。
正在运行的任务期待某一事件的发生时也要等待,手段是调用以下几个函数之一:OSFlagPend()、OSSemPend()、OSMutexPend()、OSMboxPend(),或OSQPend()。
如果某事件未发生,调用后任务进入了等待状态(WAITING)。
l 中断服务态:正在运行的任务是可以被中断的,除非该任务将中断关了,或者μC/OS-Ⅱ将中断关了。
被中断了的任务就进入了中断服务态(ISR)。
任务控制块TCB的管理1、任务块数组定义(OS_EXT OS_TCB OSTCBTbl[OS_MAX_TASKS+OS_N_SYS_TASKS];)应用程序中可以有的最多任务数(OS_MAX_TASKS)是在文件OS_CFG.H中定义的。
这个最多任务数也是μC/OS-Ⅱ分配给用户程序的最多任务控制块OS_TCBs的数目。
将OS_MAX_TASKS的数目设置为用户应用程序实际需要的任务数可以减小RAM的需求量。
手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务调度策略(五)
![手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务调度策略(五)](https://img.taocdn.com/s3/m/bf96752282c4bb4cf7ec4afe04a1b0717fd5b31b.png)
⼿把⼿,嘴对嘴,讲解UCOSII嵌⼊式操作系统的任务调度策略(五)整个UCOSII嵌⼊式操作系统的任务调度策略便是如此,现在进⾏⼀个总结:①某个任务在执⾏中,每隔⼀定周期发⽣滴答时钟中断,在中断中遍历整个任务链表,更新每个任务的延时时间,修改就绪状态。
②任务执⾏完毕后,进⼊延时函数,在延时函数中会把当前任务挂起(清空当前任务的就绪状态,使其进⼊未就绪状态),然后根据查表发找到在就绪任务中,优先级最⾼的那⼀个任务。
③找到新任务以后,⼈⼯强制发⽣⼀个中断,保存上个任务的堆栈信息,弹出下个任务的堆栈信息,同时更改PC指针,进⾏任务切换。
经过以上三个步骤,便可以完成任务的调度。
现在回到第⼀篇提出的那个问题:UCOSII到底是如何保证它的实时性的呢?如果任务的调度都是发⽣在当前任务进⼊延时之后,似乎操作系统根本⽆法⾃⾝的保障实时性。
⽐如⼀个优先级最低的任务由于某些处理⾮常耗费时间,它⼀直⽆法进⼊延时,导致⽆法进⼊任务切换,那么优先级⾼的任务反⽽是⼀只都⽆法被执⾏了……同样在第⼀篇说过,UCOSII系统除了在当前任务进⼊延时函数会发⽣调度之外,还有别的时机会进⾏任务切换: 1.当前任务进⼊了延时。
2.当前任务被挂起。
3.当前任务执⾏时,发⽣了某些中断。
第1点我们已经全部讲完,第2点⾮常好理解,我们现在看⼀个函数:OSTaskSuspend()这个函数的作⽤是把某个任务挂起(也就是不进⾏调度),现在来分析⼀个实例:有⼀个任务调⽤了这个函数:void App1_task(void *pdata){while(1){if (OS_ERR_NONE != OSTaskSuspend(OS_PRIO_SELF)){Dbg_SendStr("App1_task Suspend Error£¡\r\n");}delay_ms(10);};}当前任务执⾏了红⾊代码之后,便会把⾃⾝挂起来,如果没有再别的地⽅对它进⾏激活,这个任务便永远也不会执⾏下去了。
嵌入式实时操作系统uCOS-II(就绪算法)
![嵌入式实时操作系统uCOS-II(就绪算法)](https://img.taocdn.com/s3/m/4322d27da45177232f60a21b.png)
OSTCBTbl[1]
OSTCBStkPtr
OSTCBTbl[0]
OSTCBStkPtr
OSTCBNext
OSTCBTbl[2]
OSTCBStkPtr OSTCBNext
OSTCBTbl[n]
OSTCBStkPtr OSTCBNext NULL
OSTCBNext
NULL
20
任务控制块数组与指针
OSTCBFreeList
OSTCBPrioTbl[ ]
[0] [4] [5]
NULL
… &OSTCBTBL[1] &OSTCBTBL[2]
…
[OS_LOEEST_PRIO] &OSTCBTBL[0]
OS_TaskIdle
15
任务控制块数组与指针
OSTCBPrioTbl[
]
任务的优先级资源由操作系统提供,uc/OS-II 有64各优先级,优先级的高低按照编号从0(最高) 到63(最低)排序。由于用户实际使用的优先级的 个数通常少于64个,所以为节约系统资源,可以通 过定义系统常量OS_LOWEST_PRIO的值来限制优 先级编号的范围。
OSTCBTbl[2]
OSTCBStkPtr OSTCBNext
OSTCBTbl[n]
OSTCBStkPtr OSTCBNext NULL
NULL
13
任务控制块数组与指针
OSTCBPrioTbl[
]
任务控制块优先级表,专门用来存放指向各任 务控制块的指针,并按任务的优先级别将这些指针存 放在数组的各个元素里,这样系统在访问一个任务的 任务控制块时,就不必遍历任务控制块链表了。只要 知道任务的优先级,就可以迅速地从该数组中找到它 的任务控制块。
ucos-ii及其任务
![ucos-ii及其任务](https://img.taocdn.com/s3/m/5e99708fa0116c175f0e4843.png)
• 中断管理
1、uc/os-ii的概述 2、 uc/os-ii的任务 3、任务控制块 4、任务创建 5、uc/os-ii的初始化及任务启动
• uc/os-ii中的任务是一个线程,其代码通常是一个无 限循环结构/超循环结构,看起来像其它C 函数一样。 void mytask(void *pdata) //示意代码 { for (;;) { do something; waiting; do something; } }
uc/os-ii概述—性能特点
• 可剥夺性(Preemptive)与可确定性
内核可剥夺、函数调用或系统服务的执行时间具有 可确定性,是硬实时操作系统。
• 支持多任务
• 任务栈
uc/os-ii可以管理64个任务 每个任务有自己单独的栈,uc/os-ii允许每个任允 许每个任务有不同的栈空间,以便压低应用程序对 RAM的需求。
删除任 务
等待
等 待 时 间 到 创建任务 任务调度
挂 起
中断 运行 任务被占先 中断结束 中断任务
uc/os-ii的任务—优先级
uc/os-ii支持64个任务,每个任务有一个特定 的优先级。 任务的优先级别用数字表示,0表示的任务的 优先级最高,数字越大表示的优先级越低。 通过常数OS__LOWEST__PRIO(在 OS_CFG.H中)定义系统的最低优先级别,同 时限定系统能容纳的最多任务数量。 OS_LOWEST_PRIO给空闲任务, OS_LOWEST_PRIO-1给统计任务。
1、uc/os-ii的概述 2、 uc/os-ii的任务 3、任务控制块 4、任务的创建 5、uc/os-ii的初始化及任务启动
任务控制块—结构
任务控制块 (Task Control Blocks, OS_TCBs)是 ucos-ii用来存储任务堆栈指针、当前状态、优先级及 任务链表指针等属性的一个数据结构。 任务控制块是任务的身份证,每个任务都有一个属于 自已的任务控制块,当任务的CPU使用权被剥夺时, 任务的属性被保存在任务控制块中,而当任务重新得 到CPU使用权时任务控制块能确保任务从当时被中断 的那一点丝毫不差地继续执行。 OS_TCBs全部驻留在RAM中。 OS_TCBs 在任务建立的时候被初始化。
uCOS-II 的任务
![uCOS-II 的任务](https://img.taocdn.com/s3/m/9db657bdfd0a79563c1e727e.png)
uC/OS-II 的任务:从任务的存储结构来看,uC/OS-II的任务由三个部分构成:1任务程序代码,任务的执行部分2任务堆栈,用来保存任务工作环境3任务控制块,用来保存任务属性每一个任务都作为一个节点,组成一个双向的任务链表。
用户任务:从程序代码上看,用户任务似乎就是一个C语言函数,但是这个函数不是一般的C语言函数,它是一个任务(线程)。
因此,它不是被主函数或其他函数调用的,主函数mian()只是负责创建和启动它们,而由操作系统负责来调度它们。
系统任务:uC/OS-II预定义了两个为应用程序服务的系统任务:4空闲任务(OSTaskIdle)5统计任务(OSTaskStat)其中空闲任务是每个应用程序必须使用的。
OSTaskIdle由系统自动创建,在系统初始化时,∙OSInit --> OS_InitTaskIdle --> OSTaskIdle如果用户应用程序要使用统计任务,则必须把定义在OS_CFG.H 中的OS_TASK_STAT_EN设置为1,并且必须在创建统计任务之前调用函数OSStatInit( )对统计任务进行初始化。
任务优先级:优先级数目通过OS_CFG.H中的OS_LOWEST_PRIO配置。
固定地,系统总是把最低优先级别OS_LOWEST_PRIO自动赋给空闲任务。
如果应用程序中还使用了统计任务,则系统会把OS_LOWEST_PRIO - 1自动赋给统计任务。
由于每个任务都具有唯一的优先级别,因此uC/OS-II通常也用任务的优先级别来作为这个任务的标识。
任务堆栈:堆栈的增长方向随系统所使用的处理器不同而不同,为提高应用程序的可移植性,可利用OS_CFG.H中的OS_STK_GROWTH作为选择开关。
把CPU启动任务时所需的初始数据事先存放在任务的堆栈中,当任务获得CPU使用权时,就可以把堆栈中的初始数据复制到CPU 的各寄存器中,使任务顺利地启动并运行。
任务堆栈的初始化工作是由系统通过在OSTaskCreate ( )中调用OSTaskStkInit ( )来完成的。
嵌入式实时操作系统μCOSII原理及应用习题答案(第四版)
![嵌入式实时操作系统μCOSII原理及应用习题答案(第四版)](https://img.taocdn.com/s3/m/0dc07c87ab00b52acfc789eb172ded630b1c9801.png)
嵌入式实时操作系统μCOSII原理及应用习题答案(第四版)嵌入式实时操作系统μCOSII原理及应用习题答案(第四版)嵌入式操作系统是一种特殊的操作系统,用于控制和管理嵌入式系统。
实时操作系统(RTOS)是一种在给定的时间约束下,能够及时响应外部事件的操作系统。
μC/OS-II是一种广泛应用于嵌入式系统的实时操作系统。
本文将介绍μC/OS-II的原理及应用,并提供第四版的习题答案。
一、μC/OS-II原理1. 任务(Task)管理:μC/OS-II采用优先级抢占式调度算法,支持多任务。
每个任务具有自己的任务控制块(TCB),用于记录任务的状态、优先级、堆栈等信息。
任务之间可以通过任务切换进行调度,具有不同的优先级来确保系统的实时性。
2. 信号量(Semaphore)机制:信号量用于任务之间的同步和互斥操作。
μC/OS-II提供了两种信号量机制:二值信号量和计数信号量。
二值信号量用于任务之间的互斥操作,而计数信号量用于任务之间的同步操作。
3. 事件标志组(Event Flag Group)机制:事件标志组用于任务之间的同步和通信操作。
一个事件标志组中可以包含多个事件标志位,每个标志位都可以独立设置或清除。
任务可以等待一个或多个事件标志位的发生,并在发生时得到通知。
4. 消息邮箱(Mailbox)机制:消息邮箱用于任务之间的通信。
每个消息邮箱中可以存放一个或多个消息,任务可以通过发送和接收消息来进行通信。
消息邮箱还支持阻塞和非阻塞两种方式。
5. 定时器(Timer)管理:μC/OS-II提供了软件定时器的功能,可以设置定时器来触发任务或其他操作。
定时器可以基于时间片、滴答定时器或硬件定时器实现。
二、μC/OS-II应用1. 实时任务调度:μC/OS-II可以在多个任务之间进行优先级调度,保证任务的及时执行。
通过设置任务的优先级和时间片,可以确保高优先级任务优先执行,从而满足实时性要求。
同时,μC/OS-II还提供了任务切换和上下文切换机制,确保任务之间的切换及时有效。
嵌入式实时操作系统uCOS-II原理(课件PPT) μCOS-II中的任务管理
![嵌入式实时操作系统uCOS-II原理(课件PPT) μCOS-II中的任务管理](https://img.taocdn.com/s3/m/3d9999abdaef5ef7ba0d3ca6.png)
1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 3
1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 4
1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0
5 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0
或
prio=29 0 0 0 1 1 1 0 1
y = OSUnM图5a-6p在T就bl绪[O表S中R查d找yG最高rp优];先级别任务的过程 prio = (INT8U)((y << 3)
任当务控应制用块结程构序的主调要用成员函数OSTaskCreate( )
任务及控任制务块控(O制S_块TC链B)表 t…y创统进任务控这表…pOssIII数具链的表…ettNNNrrd…S建函行务控制个的TTTuue任_会有接任。fcc188Stts任 任 制 认6UU务T一数初从制块任头μ栈务理控tooUr当由按相为务即Kuss控__c个始空块各务部O务务块和ttt制*C指有的制cc进于用应一,相oSObbOOOs/块任化任,个控T_S**SSS控的的管行这户数个故当tT优针关O块OOC链TTTcbCSS务。务然成制BCCCS表系 些提量链这于BTT{BBBI制 身 任理先、 的-SCCDSP时这控后员块ntIBBtr统任供的表个是kliayi块 份 务的NPPot级任 属I;,个制用进链t;r;te初务的任。链一re用x///;vt///就 证 是这函块任行入(任任任/;;别务 性//始控任务表些指///指务务务来指个数链务赋到)向相 , 不等的 的向化制务控叫空等的的向来任记函首表的值任后待当优前时块数制做白当 没 能务为一当 表一的前先一空数先获属,务堆录个,还为块空的时状级个任任于 有 被栈些前 就会为取性最控任限态别任务初没系并任身任栈务务标(务是 任 系控与状 叫调 被 一 对后 制顶控始有统 把务份志节控控制务的用创个任再块制拍一务统制任态做块化对创它块证指制块数块的链系建任务把链针个控承的函应建们链。)务任、的块表指堆指管任务针针
ucosii任务管理及调度
![ucosii任务管理及调度](https://img.taocdn.com/s3/m/99c29e7fa98271fe910ef9e5.png)
统计任务OSTaskStat(),提供运行时间统计。每 秒钟运行一次,计算当前的CPU利用率。其优先级 是OS_LOWEST_PRIOR-1,可选。
22
任务控制块TCB 任务控制块 OS_TCB是描述一个任务的核 心数据结构,存放了它的各种管理信息 ,包括任务堆栈指针,任务的状态、优 先级,任务链表指针等;
11
µC/OS-II的各种商业应用
全世界有数百种产品在应用:
Avionics Medical Cell phones
Routers and switches
High-end audio equipment Washing machines and dryers UPS (Uninterruptible Power Supplies)
19
任务也可以自我删除(并非真的删除,只是内核不 再知道该任务)
void MyTask (void *pdata) {
ucOSII操作系统就绪表分析
![ucOSII操作系统就绪表分析](https://img.taocdn.com/s3/m/65f5cd9adc88d0d233d4b14e852458fb770b387c.png)
ucOSII操作系统就绪表分析在ucOSII的绪表中使⽤⼀个很妙的查找⽅式,下⾯对其查找过程进⾏详细分析(⽬的就是加快查找速度)对于ucOSII⽽⾔,其最⼤的任务数是64个,因此为了标记其任务的状态,ucOSII使⽤了⼋个变量表⽰每个任务的状态,每个变量每个位对应任务的状态:如果我们直接去查找就绪任务的最⾼优先级任务,那我们需要遍历这⼋个变量,去判断最⾼位是1,很显然在最坏情况下需要遍历64次,那有没有更好的⽅法呢,仔细观察发现⼀个规律,当任务优先级是8的时候,其就绪标志位在OSRdyTbl[1]中的第0位,8对应的⼆进制是00001000,这样00001正好是1,000正好是0,我们在看看其他是不是这样,例如7的⼆进制00000111,00000对应的是0,也就是OSRdy[0],111对应7,也就是第7位,继续验证发现确实所有的优先级都满⾜这个规律,因此我们可以利⽤这⼀点来加快查找速度。
这样我们就有如下结构:实际上有OSRdyl的下标表⽰中只有3,4,5三位有效,因为这⾥只有8组,不过这个⽆所谓,都是⼀样的。
为了表⽰这些组中有没有就绪任务,ucOSII中定义了⼀个OSRdyGrp这个变量,该变量是⼀个8位的⽆符号整型,这样每⼀位表⽰每个组有⽆就绪任务:这样OSRdyGrp的初始值为0,当有⼀个任务创建时,那就将该任务所在的组(即OSRdyTbl)对应的OSRdyGrp相应的位设置为1,当有任务删除时,那就将该任务所在的组对应的OSRdyGrp相应的位设置为0,如下:创建任务(登记): OSRdyTbl[prio>>3] |= (prio&0x07); OSRdyGrp |= (prio>>3);删除任务(注销): OSRdyTbl[prio>>3] &= ~(prio&0x07); OSRdyGrp &= ~(prio>>3);在ucOSII中为了加快速度,定义了⼀个数组const UINT8 OSMapTbl[8](说明:这⾥可以看到OSRdyGrp对其⼀个变量位操作会通过很多指令完成,但是如果对⼀个固定的常量进⾏位操作就减少很多指令)这样上⾯的操作就变为了如下操作:创建任务(登记): OSRdyTbl[prio>>3] |= OSMapTbl [prio&0x07]; OSRdyGrp |= OSMapTbl [(prio>>3)];删除任务(注销): OSRdyTbl[prio>>3] &= ~OSMapTbl [prio&0x07]; OSRdyGrp &= ~OSMapTbl [(prio>>3)];这样就完成了任务创建和删除时对就绪表的操作,在ucOSII中还需要涉及到最⾼优先级查找,因为当当前运⾏任务进⼊阻塞态时,下⼀个运⾏任务就应该时最⾼优先级任务,因此我们必须找到最⾼优先级的任务,显然,我们需要找到数组中OSRdyTbl的为1的最⾼位在哪。
《嵌入式实时操作系统uC OS-2教程》课件第5章
![《嵌入式实时操作系统uC OS-2教程》课件第5章](https://img.taocdn.com/s3/m/4c15309d9fc3d5bbfd0a79563c1ec5da50e2d63d.png)
第5章 事件控制块
5.4 在等待事件的任务列表中查找 优先级最高的任务
当事件发生后,由于可能有一个或者多个任务在等待该 事件,因此就要在事件的任务等待列表中查找优先级最高的 任务。为了提高查找速度,查找的方法不是从 .OSEvent Tbl[0]开始逐个查询,而是采用了查表的办法,这个表是 OS_CORE.C文件中的定义的OSUnMapTbl[256],其内容如 程序清单5.4所示。在等待事件的任务列表中查找优先级最 高的任务具体实现算法如下:
};
第5章 事件控制块
程序清单5.5 在等待事件的任务列表中查找优先级最高的任 务的代码 y = OSUnMapTbl[pevent->OSEventGrp]; x = OSUnMapTbl[pevent->OSEventTbl[y]]; prio = (y<<3) + x;
(3) 计算最高优先级:Prio = y × 8 + x 这样,最终就可以得到处于等待该事件状态的最高优先 级任务了,其代码如程序清单5.5所示。
第5章 事件控制块
程序清单5.4 OSUnMapTbl[]的内容 INT8U const OSUnMapTbl[] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x00 to 0x0F 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x10 to 0x1F 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x20 to 0x2F 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x30 to 0x3F 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x40 to 0x4F 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x50 to 0x5F 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x60 to 0x6F 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //0x70 to 0x7F
Uc-OS II就绪表(Ready List)分析
![Uc-OS II就绪表(Ready List)分析](https://img.taocdn.com/s3/m/33233c427cd184254b353585.png)
Uc/OS II 就绪表(Ready List)分析就绪表(Ready List)每个任务被赋予不同的优先级等级,从0 级到最低优先级OS_LOWEST_PR1O,包括0 和OS_LOWEST_PR1O 在内(见文件OS_CFG.H)。
当uCOS II 初始化的时候,最低优先级OS_LOWEST_PR1O 总是被赋给空闲任务idle task。
注意,最多任务数目OS_MAX_TASKS 和最低优先级数是没有关系的。
用户应用程序可以只有10 个任务,而仍然可以有32 个优先级的级别(如果用户将最低优先级数设为31 的话)。
每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRedyGrp和OSRdyTbl[]。
在OSRdyGrp 中,任务按优先级分组,8 个任务为一组。
OSRdyGrp 中的每一位表示8 组任务中每一组中是否有进入就绪态的任务。
任务进入就绪态时,就绪表OSRdyTbl[]中的相应元素的相应位也置位。
就绪表OSRdyTbl[]数组的大小取决于OS_LOWEST_PR1O(见文件OS_CFG.H)。
当用户的应用程序中任务数目比较少时,减少OS_LOWEST_PR1O 的值可以降低uCOS II 对RAM(数据空间)的需求量。
为确定下次该哪个优先级的任务运行了,内核调度器总是将OS_LOWEST_PR1O 在就绪表中相应字节的相应位置1。
OSRdyGrp 和OSRdyTbl[]之间的关系见图3.3,是按以下规则给出的:当OSRdyTbl[0]中的任何一位是1 时,OSRdyGrp 的第0 位置1,当OSRdyTbl[1]中的任何一位是1 时,OSRdyGrp 的第1 位置1,当OSRdyTbl[2]中的任何一位是1 时,OSRdyGrp 的第2 位置1,当OSRdyTbl[3]中的任何一位是1 时,OSRdyGrp 的第3 位置1,当OSRdyTbl[4]中的任何一位是1 时,OSRdyGrp 的第4 位置1,。
嵌入式操作系统教程-第五章
![嵌入式操作系统教程-第五章](https://img.taocdn.com/s3/m/eef602d87f1922791688e8ea.png)
嵌 入 式 操 作 系 统 基 础 第 五 章 uC/OS-II
§5.2 任务的创建
1.任务创建必须完成的三大工作:任务堆栈的初始 化、任务控制块的初始化和任务调度。
创建函数OSTaskCreate() 创建函数OSTaskCreate() 创建函数OSTaskCreateExt() 创建函数OSTaskCreateExt()
2
嵌 入 式 操 作 系 统 基 础 第 五 章 uC/OS-II
变量OSRedyGrp和OSRdyTbl[]的对应关系: 变量OSRedyGrp和OSRdyTbl[]的对应关系: OSRedyGrp 的对应关系
当OSRdyTbl[0]中的任何一位是1时,OSRdyGrp的第0位置1, 当OSRdyTbl[1]中的任何一位是1时,OSRdyGrp的第1位置1, 当OSRdyTbl[2]中的任何一位是1时,OSRdyGrp的第2位置1, 当OSRdyTbl[3]中的任何一位是1时,OSRdyGrp的第3位置1, 当OSRdyTbl[4]中的任何一位是1时,OSRdyGrp的第4位置1, 当OSRdyTbl[5]中的任何一位是1时,OSRdyGrp的第5位置1, 当OSRdyTbl[6]中的任何一位是1时,OSRdyGrp的第6位置1, 当OSRdyTbl[7]中的任何一位是1时,OSRdyGrp的第7位置1,
嵌 入 式 操 作 系 统 基 础 第 五 章 uC/OS-II #if OS_TASK_DEL_EN INT8U OSTaskDel (INT8U prio) ;
3.任务删除函数
4.查询任务信息
INT8U OSTaskQuery ( INT8U prio, OS_TCB *pdata )
12
3
嵌 入 式 操 作 系 统 基 础 第 五 章 uC/OS-II
嵌入式系统 第5章 uCOS操作系统的应用PPT课件
![嵌入式系统 第5章 uCOS操作系统的应用PPT课件](https://img.taocdn.com/s3/m/9dc8eb57763231126edb1163.png)
三菱公司
M16和M32
摩托罗拉公司
PowerPC,
飞利浦公司
XA
西门子公司
80C166和TriCore
TI公司
TMS320
Zilog公司
Z—80 和Z—180
2
μC/OS-II意为“微控制器操作系统版本2”。 世界上已有数千人在各个领域使用μC/OS, 例如,照相机行业、医疗器械、音响设施、 发动机控制、网络设备、高速公路电话系统、 自动提款机、工业机器人等等。很多高等院 校将μC/OS用于实时系统教学。
5.可剥夺型(Preemptive),µC/OS-Ⅱ是完全可剥 夺型的实时内核,运行就绪条件下优先级最高的任务。
6.多任务,µC/OS-Ⅱ可管理64个任务。一般情况下, 建议用户保留8个任务给µC/OS-Ⅱ。这样,留给用户 应用程序的任务最多可有56个。系统赋给每个任务的优 先级必须不同,这意味着µC/OS-Ⅱ不支持时间片轮转 调度法(Round-robin Scheduling)。
①任务延时函数OSTimeDIy()
调用该函数会使µC/OS-Ⅱ进行一次任务调度,并且执行下 一个优先级最高的就绪态任务。任务调用OSTimeDly()后,一 旦规定的时间期满或者有其他任务通过调用 OSTimeDlyResume()取消了延时,它就会立即进入就绪状态。 只有当该任务在所有就绪任务中具有最高的优先级时,它才会立 即运行。
Ⅱ的每一种功能、每一个函数及每一行代码都经过了考
验与测试。
11
5.1.2 µC/OS-Ⅱ系统的内核结构
与其他操作系统不同,µC/OS-Ⅱ其实只有一个内 核,提供任务调度、任务间的通信与同步、任务管理、 时间管理和内存管理等基本功能。
1) 任务
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
多任务操作系统的核心工作就是任 务调度。
所谓调度,就是通过一个算法在多
μ的个作C的任依/函μ务OC数中/据任OS就确S__叫务就定III进做该I进就行是调运任及度行绪行任务器的调。表任任务度务的,务就思做想调这绪是项度表工
任务调度 “近似地每时每刻总是让优先级最高的
任任就务务就就绪绪绪任表表务和和任任处务务于就就运绪绪组组行的的状结登态构记、”注销。、为了保证 最这高优一先点级,就绪它任在务系的查统找或用户任务调用系统
先保护被中 止任务的断
点数据
后恢复待运 行任务的断
点数据
不要企图用PUSH和POP指令来使程序计数 器PC压栈和出栈,因为没有这样的指令。
只好需一变次要通由中一宏断下或O了S_者。TA一SK次_S调W(用)来来使引发 中断动作和过OS程Ct调xS用w指( 令) 可以使PC压栈; 中断返回指令可以执使行P任C出务栈切。换工作
嵌入式实时操作系统
μC/OS-II
信息学院
3.3任务控制块 (OS_TCB)
及其链表
μC/OS-II用来记录任务的堆
栈指针、任务的当前状态、任 务的优先级别等一些与任务管 理有关的属性的表就叫做任务 控制块
任务控制块就相当于是一个任 务的身份证,没有任务控制块 的任务是不能被系统承认和管 理的
任务控制块结构的主要成员
5 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0
6 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0
7 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 y
任务就绪表的示意图
D7 D6 D5 D4 D3 D2 D1 D0 prio=29 0 0 0 1 1 1 0 1
};
优先级判定表OSUnMapTbl[256]
OSUnMapTbl[]这个数组的生成原则:先 把一个数用二进制表示,然后从低位往高 位数,返回第一次碰到1的位置。比如: OSUnMapTbl[0x111100(60)] = 2。可 以看到,如果要表示8位数的对应关系, 则数组的大小为2^8=256。这也是为什么 OSRdyTbl[],OSRdyGrp采用8位的原因。
OSRdyGrp D7 D6 D5 D4 D3 D2 00 1 0 1 0
D1 D0 00
OSRdyTbl[y ] D7 D6 D5 D4
0110
D3 D2 00
D1 D0 00
y = OSUnMapTal[OSRdyGrp];
x= OSUnMapTal[OSRdyTbl[y]];
D7 D6 D5 D4 D3 D2 D1 D0 prio=29 0 0 0 1 1 1 0 1
typedef struct os_tcb { OS_STK *OSTCBStkPtr; //指向任务堆栈栈顶的指针
…… struct os_tcb *OSTCBNext;//指向后一个任务控制块的指针 struct os_tcb *OSTCBPrev; //指向前一个任务控制块的指针
…… INT16U INT8U INT8U
根据就绪表获得 获 待得 运待 行运 任行 务任 的务任 的 务任 控务 制控 块制 指块 针
处理器的SP=任 务块中保存的SP
恢复待运行任务 的运行环境
处理器的PC=任 务堆栈中的断点 地址
如何获得待运行 任务的任务控制
块?
任务切换宏 OS_TASK_SW( )
任务切换就是中止正在运行的任务 (当前任务),转而去运行另外一个 任务的操作,当然这个任务应该是就 绪任务中优先级别最高的那个任务
OSRdyGrp | =OSMapTbl[prio>>3]; Y
X OSRdyTbl[prio>>3]
| = OSMapTbl[prio&0x07];
OSRdyGrp
OSRdyTbl[3 ]
D7 D6 D5 D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0
1
1
把prio为29的任务置为就绪状态
//output this tab for(n=0;n<=0xff;n++) {
if(n%0x10==0) printf("\n");
printf("%3d" , tab[n]); } printf("\n"); }
小结
系统通过查找任务就绪表来 获取待运行任务的优先级
优先级
任务切换过程
其实,调度 器在进行调 度时,在这 个位置还要 进行一下判 断:究竟是 待运行任务 是否为当前 任务,如果 是,则不切 换;如果不 是才切换, 而且还要保 存被中止任 务的运行环
while(i=0;i<8;i++){ if(OSRdyGrp%2!=0) break; else OSRdyGrp=OSRdyGrp/2;
}y=i; while(i=0;i<8;i++){
if(OSRdyTbl[y]%2!=0) break; else OSRdyTbl[y]=OSRdyTbl[y]/2; }x=i; prio=y*8+x;
OSRdyGrp&=~OSMapTbl[prio>>3];
在就绪表中查找最高优先级任务
已经知道OSRdyGrp和OSRdyTbl 求优先级最高的任务的优先级,也就是先求 OSRdyGrp的从最低位找,第一个为1的位 置y;再求OSRdyTbl[y]的从最低位找,第 一个为1的位置x;prio=y*8+x; char OSRdyGrp,OSRdyTbl[8]; 如何编程实现?
或
y = OSUnMapTbl[OSRdyGrp]; prio = (INT8U)((y << 3)
+ OSUnMapTbl[OSRdyTbl[y]]);
优先级判定表OSUnMapTbl[256] (os_core.c)
举例: 如OSRdyGrp的值为
00101000B,即0X28,则 查得 OSUnMapTbl[OSRdyGrp] 的值是3,它相应于 OSRdyGrp中的第3位置1;
在程序中,可以用类似下面的代码把优先 级别为prio的任务置为就绪状态:
OSRdyGrp | =OSMapTbl[prio>>3]; OSRdyTbl[prio>>3] | = OSMapTbl[prio&0x07];
如果要使一个优先级别为prio的任务脱离就绪 状态则可使用如下类似代码:
if((OSRdyTbl[prio>>3]&=~OSMapTbl[prio&0x07])== 0)
OSTCBDly; //任务等待的时限(节拍数) OSTCBStat; //任务的当前状态标志 OSTCBPrio; //任务的优先级别
…… } OS_TCB;
当进行系统初始化时,初始化函 数会按用户提供的任务数为系统创建 具有相应数量的任务控制块并把它们 链接为一个链表。
由于这些任务控制块还没有对应 的任务,故这个链表叫做空任务块链 表。即相当于是一些空白的身份证。
任务控制块链表
空任务控制块链表
当应用程序调用函数OSTaskCreate( )创 建一个任务时,这个函数会调用系统函数 OSTCBInit ( )来为任务控制块进行初始 化。这个函数首先为被创建任务从空任务 控制块链表获取一个任务控制块,然后用 任务的属性对任务控制块各个成员进行赋 值,最后再把这个任务控制块链入到任务 控制块链表的头部
图5-6 在就绪表中查找最高优先级别任务的过程
从任务就绪表中获取优先级别最高的就绪任务可用如下 类似的代码:
y = OSUnMapTal[OSRdyGrp]; //D5、D4、D3位
x = OSUnMapTal[OSRdyTbl[y]]; //D2、D1、D0位
prio = (y<<3)+x;
//优先级别
再从代码生成的角度看看是如何得到这个 表的?
编程生成优先级判定表OSUnMapTbl[256]
#include <stdio.h> int main(void) {
int i,t,n; int tab[256]={0}; for(i=0;i<8;i++)
for(t=1;(t<<i)<256;t++) tab[t<<i]=i;
函数及执行中断服务程序结束时总是调 用调度器,来确定应该运行的任务并运 行它 。
为了能够使系统清楚地知道,系统中 哪些任务已经就绪,哪些还没有就绪, μC/OS_II在RAM中设立了一个记录 表,系统中的每个任务都在这个表中 占据一个位置,并用这个位置的状态 (1或者0)来表示任务是否处于就绪 状态,这个表就叫做任务就绪状态表, 简称叫任务就绪表
3.4任务就绪表 及
任务调度
多任务操作系统的核心工作就是任务调 度。
所谓调度,就是通过一个算法在多个任 务中确定该运行的任务,做这项工作的函数 就叫做调度器。
μC/OS_II进行任务调度的思想是 “近 似地每时每刻总是让优先级最高的就绪任务 处于运行状态” 。为了保证这一点,它在 系统或用户任务调用系统函数及执行中断服 务程序结束时总是调用调度器,来确定应该 运行的任务并运行它 。
因此任务切换OSCtxSw( )必定是一个中断 服务程序。
调度时机
对于实时系统来说,应该尽 可能地实现即时调度。
用函数OSTaskCreate( ) 创建任务
应用程序通过调用OSTaskCreate( ) 函数来创 建一个任务,OSTaskCreate( )函数的原型如下:
INT8U OSTaskCreate ( void (*task)(void *pd),//指向任务的指针 void *pdata, //传递给任务的参数 OS_STK *ptos, //指向任务堆栈栈顶的指针 INT8U prio //任务的优先级