嵌入式操作系统_第5章 ucOS-II - 任务就绪表及任务就绪组

合集下载

UCOS任务就绪表的理解

UCOS任务就绪表的理解

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

实验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表格的由来

μ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复习指南

复习:第一章:实时操作系统、操作系统基本功能、任务、多任务、任务状态及相互关系、任务切换、可重入和不可重入;可剥夺和不可剥夺内核;同步与通信:同步、互斥、临界区、事件、信号量、互斥信号量、消息邮箱、消息队列;中断、时钟、内存管理。

第二章:任务管理:任务控制块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学习

嵌入式系统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嵌入式操作系统的任务调度策略(五)

⼿把⼿,嘴对嘴,讲解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(就绪算法)

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及其任务

• 中断管理
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 在任务建立的时候被初始化。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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 //任务的优先级
相关文档
最新文档