嵌入式操作系统_第5章 ucOS-II - 任务就绪表及任务就绪组
- 格式:ppt
- 大小:1.35 MB
- 文档页数:47
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个就绪表来确定,应为那样遍历的时间是不确定的。
实验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。
μ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位。
复习:第一章:实时操作系统、操作系统基本功能、任务、多任务、任务状态及相互关系、任务切换、可重入和不可重入;可剥夺和不可剥夺内核;同步与通信:同步、互斥、临界区、事件、信号量、互斥信号量、消息邮箱、消息队列;中断、时钟、内存管理。
第二章:任务管理:任务控制块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学习/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嵌⼊式操作系统的任务调度策略便是如此,现在进⾏⼀个总结:①某个任务在执⾏中,每隔⼀定周期发⽣滴答时钟中断,在中断中遍历整个任务链表,更新每个任务的延时时间,修改就绪状态。
②任务执⾏完毕后,进⼊延时函数,在延时函数中会把当前任务挂起(清空当前任务的就绪状态,使其进⼊未就绪状态),然后根据查表发找到在就绪任务中,优先级最⾼的那⼀个任务。
③找到新任务以后,⼈⼯强制发⽣⼀个中断,保存上个任务的堆栈信息,弹出下个任务的堆栈信息,同时更改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);};}当前任务执⾏了红⾊代码之后,便会把⾃⾝挂起来,如果没有再别的地⽅对它进⾏激活,这个任务便永远也不会执⾏下去了。
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原理及应用习题答案(第四版)嵌入式操作系统是一种特殊的操作系统,用于控制和管理嵌入式系统。
实时操作系统(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还提供了任务切换和上下文切换机制,确保任务之间的切换及时有效。