资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第,3,章,COS_II,中的任务,通信工程教研室,嵌入式,RTOS,C,/OS-II,简介,C,/OS,由,Jean J.,Labrosse,先生(加拿大),1992,编写的,RTOS,,,1999,年改写后命名为,C,/OS-II,。,2000,年被美航空管理局认证。,C,/OS-II,中的代码,90%,用,C,语言编写,有少量的相关于硬件的代码用汇编编写,易移植到各类体系结构的,8,位、,16,位、,32,位处理器。,官方网站:,www.uCOS-II.com,C,OS-,体系结构,typedef,unsigned char,BOOLEAN;,typedef,unsigned char,INT8U;/*8,位无符号整数*,/,typedef,signed char,INT8S;/*8,位有符号整数*,/,typedef,unsigned short,INT16U;/*16,位无符号整数*,/,typedef,signed short,INT16S;/*16,位有符号整数*,/,typedef,unsigned long,INT32U;/*32,位无符号整数*,/,typedef,signed long,INT32S;/*32,位有符号整数*,/,typedef,float,FP32;/*,单精度浮点数*,/,typedef,double,FP64;/*,双精度浮点数*,/,typedef,unsigned short,OS_STK;,/*Each stack entry is 16-bit wide*/,os_cpu.h,(,C,/OS-II,中的数据类型,),#define BYTE,INT8S /,字节,#define UBYTE,INT8U,#define WORD,INT16S /,半字,#define UWORD,INT16U,#define LONG,INT32S /,字,#define ULONG,INT32U,/*Define data types for backward compatibility.*/,/*.to,uC,/OS V1.xx.Not actually needed for.*/,/*.,uC,/OS-II.,*/,#define,OS_STK_GROWTH 1 /,堆栈增长方式,.,os_cpu.h,(,C,/OS-II,中的数据类型,),堆栈增长方式,堆栈是一个按特定顺序进行存取的存储区,操作顺序为“,后进先出,”。,堆栈寻址是隐含的,它使用一个专门的寄存器,(,堆栈指针,),指向一块存储区域,(,堆栈,),,指针所指向的存储单元即是堆栈的栈顶。,存储器堆栈可分为两种:,向上生长:向高地址方向生长,称为递增堆栈,向下生长:向低地址方向生长,称为递减堆栈,栈底,栈顶,栈区,SP,堆栈存储区,栈顶,栈底,栈区,SP,向下增长,向上增长,0 x12345678,0 x12345678,堆栈压栈,堆栈压栈,堆栈增长方式,堆栈指针,栈顶,SP,栈顶,SP,栈底,空堆栈,栈底,满堆栈,0 x12345678,0 x12345678,栈顶,SP,0 x12345678,栈顶,SP,压栈,压栈,堆栈指针指向最后压入的堆栈的有效数据项,称为,满堆栈,;,堆栈指针指向下一个待压入数据的空位置,称为,空堆栈,。,堆栈方式,四种类型的堆栈方式:,满递增,:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如,LDMFA,、,STMFA,等;,空递增,:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如,LDMEA,、,STMEA,等;,满递减,:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如,LDMFD,、,STMFD,等;,空递减,:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如,LDMED,、,STMED,等。,本章主要内容,1,、任务的基本概念,2,、任务堆栈,3,、任务控制块及任务控制块链表,4,、任务就绪表及任务调度,5,、任务的创建,6,、任务的挂起和恢复,7,、其他任务管理函数,8,、,uC,/OS-II,的初始化和任务的启动,本章主要内容(补充),1,、任务的特性,2,、任务的划分目标,3,、任务的划分方法,4,、任务的可调度性分析,5,、任务的执行分类和优先级安排,6,、任务设计中的问题,7,、系统设计编码实现过程,8,、中断服务程序的设计,3.1,任务的基本概念,3.1.1,任务及其内存结构,问题解题思路:复杂问题,“,分而治之”。,针对目标系统拆分后的“小”且“易”的问题处理方法,其编码和数据结构的程序实体,-,任务,。,C,/OS-II,的两种任务:,系统任务,:为应用程序或系统本身提供某种服务;,用户任务,:为实现某些具体应用编写的。,C,/OS-II,的任务代码上为一函数,其组成:,任务控制块,-,uC,/OS-II,进行任务管理用的一个数据结构,记录任务的各个属性。,任务代码,-,描述任务算法的程序编码,任务堆栈,-,保存任务的工作现场环境,。,3.1.1,任务的基本概念,C,/OS-II,的任务代码上为一函数,其组成:,任务控制块,-,uC,/OS-II,进行任务管理用的一个数据结构,记录任务的各个属性。,任务代码,-,描述任务算法的程序编码。,任务堆栈,-,保存任务的工作现场环境。,3.1.1,任务的基本概念,(进程:具有自己的私有运行空间;),(线程:没有自己的私有运行空间;),C,/OS-,没有给任务定义私有运行空间,因此,C,/OS-,的所有任务都属于线程;,系统可以根据任务控制块了解代码的相关信息,也能够找到该任务相关代码;,C,/OS-,利用任务控制块链表对任务进行管理。,C,/OS-,目前支持,64,个任务。,3.1.1,任务的基本概念,3.1.2,任务的状态,Sleep,(休眠),-,仅有编码未激活;未被分配任务控制块。,Ready,(就绪),-,已激活并“万事俱备,只欠调度”,就绪表中已经登记,,Running,(运行),-,已经获得,CPU,的使用权。,Wait,(等待),-,等待某事件发生。,ISR_Sta,(被中断),-Running,状态的任务被中断后进入的状态。,3.1.2,任务的状态,正在运行的任务,需要等待一段时间或需要等待一个事件发生再运行时,该任务就会把,CPU,的使用权让给别的任务而使任务进入等待状态,。,任务在没有被配备任务控制块或被剥夺了任务控制块时的状态叫做任务的休眠状态,系统为任务配备了任务控制块且在任务就绪表中进行了就绪登记,这时任务的状态叫做就绪状态。,处于就绪状态的任务如果经调度器判断获得了,CPU,的使用权,,则任务就进入运行状态,一个正在运行的任务一旦响应中断申请就会中止运行而去执行中断服务程序,这时任务的状态叫做中断服务状态,3.1.3,任务的状态,用户任务代码的一般结构,void,MyTask(void,*,pdata,),/,“,void”,可传递任何类型数据,/,任务的初始化,for(;),/,超循环结构,构成任务体,可被中断的用户代码片断;,OS_ENTER_CRITICAL();,/,宏,进入临界区(关中断),不可被中断的用户代码片断;,OS_EXIT_CRITICAL();,/,宏,,退出临界区(开中断),可被中断的用户代码片断;,3.1.3,任务的状态,用户应用程序的一般结构,“用户任务”代码形式上很像,C,函数,但不是函数!,“任务”不能被主函数,main(),或其他函数调用,只能被主函数或已激活任务,创建,;,“任务”和,main(),地位平等;,“任务”的运行由操作系统调度管理;,main(),是整个程序的入口,不调用任务,但负责任务的创建并将创建的任务交给系统,何时运行任务则与,main(),无关。,3.1.3,任务的状态,用户应用程序的一般结构,void,MyTask1,(void*,pdata,)/,定义用户任务,1,for(;),void,MyTask2,(void*,pdata,),for(;),void,MyTask2,(void*,pdata,),for(;),3.1.3,任务的状态,用户应用程序的一般结构,void main(),OSInit,();/,系统初始化,OSTaskCreate,(MyTask1,);/,创建任务,1,OSTaskCreate,(MyTask2,);,OSTaskCreate,(MyTask3,);,OSStart,();/,启动任务,3.1.3,任务的状态,用户应用程序的一般结构,OSInit,(),函数原型:,void,OSInit,(void),OSStar,(),函数原型:,void,OSStart,(void),OSTaskCreate,(),函数原型:,INT8U,OSTaskCreate,(,void(*,task)(void,*pd),/,指向任务的指针,void*,pdata,/,传递给任务的参数,OS_STK*,ptos,/,任务堆栈栈顶的指针,INT8U,prio,/,任务的优先级别,),3.1.3,任务的状态,OSTaskCreate,(),函数使用举例:,/,定义任务,task_A,void,task_A(void,*,pdata,),;,/,任务初始化部分,while(1),;,/,任务功能代码,/,在系统“创建”任务,task_A,void,main(void,),OSInit,();,/,系统初始化部分,OSTaskCreate,(,task_A,void*0,&,MystackTop,8,);,OSStart,();,3.1.4,系统任务,空闲任务,OSTaskIdel,(),C,/OS-II,规定用户程序中必须使用,OSTaskIdel,。,该任务不能用软件删除。,该任务是,C,/OS-II,初始化时自动创建,其任务优先级固定为最低级,用户也可修改该任务的业务。,目的,-,使,CPU,在没有用户任务可执行时也有事可做。,原型:,void,OSTaskIdel(void,*,pdata,),3.1.4,系统任务,空闲任务,OSTaskIdel,(),Void,OSTaskIdel,(),#if OS_CRITICAL_MATHOD=3,OS_CPU_SR,cpu_sr,;,#,endif,pdata,=,pdata,;/,为防止编译错误,for(;),OS_ENTER_CRITICAL();/,进入中断,OSdleCtr,+;/,任务运行次数计数器加,1,OS_EXIT_CRITICAL();/,退出中断,3.1.4,系统任务,统计任务,OSTaskStat,(),功能:每秒钟计算一次,CPU,单位时间内被使用的时间,即完成用户任务,CPU,使用率的统计,结果以百分比的形式存放在变量,OSCPUsage,中。,该任务用户可选择使用。,OS_CFG.H,文件中的常数,OS_TASK_STAT_EN,设置为,1,,使能该函数。,用户在,OS_CFG.H,中使能该任务后,系统自动创建该任务,但在用户使用统计数据前必须调用系统函数,OSStatInit,(),先进行初始化。,该任务固定拥有次末任务优先级。,原型:,void,OSTaskStat(void,*,pdata,),3.1.5,任务的优先权和优先级,C,/OS-II,采用,优先级抢占式,规则,选择任务运行。,C,/OS-II,的每个任务都必须有,唯一,的优先级。,C,/OS-II,最多可以管理,64,个优先级别分配给,64,个任务,从,063,。,C,/OS-II,中用一个,8b,的整型数来表示优先级别,,数字越小,优先级越高,,,prio,=0,的任务优先级最高。,C,/OS-II,中使用任务的优先级(,prio,)作为,任务句柄,。,用户通过修改,OS_CFG.H,中的宏定义常数,OS_LOWEST_PRIO,的值,约定本用户系统的最大优先级数。,系统自动将,OS_LOWEST_PRIO,的值付给空闲任务,将,OS_LOWEST_PRIO-1,的值付给统计任务。,每个任务具有唯一的优先级,因此优先级别也是任务在系统中的标识。,3.2,任务堆栈,堆栈,-,后进先出,LIFO,访问原则组织的连续 存储器。,任务堆栈在,uC,/OS-II,中的应用:,任务堆栈是任务的三大组成部分之一。,保存,CPU,寄存器现场(,R0R12,、,LR,、,SPSR,等)。,本,Task,的私有数据。,3.2.1,任务堆栈的创建,在创建任务的同时,任务堆栈即被创建。,在,OS_CPU.H,中定义堆栈数据类型,OS_STK,typedef,unsigned,int,OS_STK,#define,MyTaskStkSize,64,OS_STK,MyTaskStk,MyTaskStkSize,/,在,OS_CPU.H,中定义,OS_STK,/,typedef,INT32U OS_STK,INT8U,OSTaskCreate,(,void(*task)(void*pd),/,指向任务的指针,void*,pdata,/,传递给任务的参数,MyTaskStk,MyTaskStkSize,1,/,任务堆栈,栈顶,的指针,INT8U,prio,/,任务的优先级别,),3.2.1,任务堆栈的创建,任务堆栈的使用注意事项:存在两种堆栈形式,递增堆栈,-,进栈操作向大地址方向发展。,递减堆栈,-,进栈操作向小地址方向发展。,OSTaskCreate,(,&,MyTaskStkStkSize,-1,),OSTaskCreate,(,&,MyTaskStk,0,),备注:利用,条件编译,技术和,OS_CPU.H,中的宏定义常数,OS_STK_GROWTH,编写易移植用户系统;,“,1”-,递减堆栈,for ARM CPU,。,3.2.2,任务堆栈的初始化,初始化:指向任务的指针、任务堆栈指针、程序状态字等事先存放在任务堆栈中;,堆栈初始化函数:,OS_STK,OSTaskStkInit,(),该函数由,C,/OS-II,提供的任务创建函数,OSTaskCreate,(),调用,用户一般不接触。,OS_STK,OSTaskStkInit,(,void(*task)(void*pd),void*,pdata,OS_STK*,ptos,,,INT16U opt,),3.3,任务控制块及其链表,任务控制块(,TCB,),-,任务在系统中的身份证,TCB-,uC,/OS-II,中用于记录任务信息(任务,堆栈指针,、,任务当前状态,、,任务优先级别,等)的数据结构。,没有任务控制块的任务不能被系统承认和管理;,uC,/OS-II,将系统中的所有,TCB,构成两个链表(,OSTCBList,、,OSTCBFreeList,)进行任务管理,空任务控制块链表,-,未被分配的,TCB,链,OSTCBFreeList,。,任务控制块链表,-,已分配的,TCB,链,OSTCBList,3.3.1,任务控制块的结构,任务控制块结构的主要成员:,typedef,struct,os_tcb,struct,os_tcb,*,OSTCBNext,;,/,指向下一个,TCB,的指针,struct,os_tcb,*,OSTCBPrev,;,/,指向前一个,TCB,的指针,OS_STK *,OSTCBStkPtr,;,/,指向任务堆栈栈顶的指针,INT16U,OSTCBDly,;,/,任务等待时限,(,节拍数,),INT8U,OSTCBStat,;,/,任务的当前状态标志,INT8U,OSTCBPrio,;,/,任务的优先级别,OS_TCB,;,3.3.1,任务控制块的结构,OSTCBStat,存放任务的当前状态标志,值,说 明,OS_STAT_RDY,表示任务处于就绪状态,OS_STAT_SEM,表示任务处于等待信号状态,OS_STAT_MBOX,表示任务处于等待消息邮箱状态,OS_STAT_Q,表示任务处于消等待息队列状态,OS_STAT_SUSPEND,表示任务处于被挂起状态,OS_STAT_MUTEX,表示任务处于等待互斥型信号量状态,3.3.2,任务控制链表,uC,/OS-II,将系统中的所有,TCB,构成两个链表(,OSTCBList,、,OSTCBFreeList,)进行任务管理,空任务控制块链表,-,未被分配的,TCB,链,OSTCBFreeList,。,任务控制块链表,-,已分配的,TCB,链,OSTCBList,3.3.2,任务控制链表,空任务控制块链表,-,未被分配(空白)的,TCB,链表,OSTCBFreeList,。,OSTCBFreeList,由,OSInit,(),在,RAM,中由系统自建;,OSTCB1OS_MAX_TASKS,:,用户最大任务数;,(OS_CFG.H,中定义,),OS_N_SYS_TASKS,:系统任务数;,(,uCOS_II.H,中定义,),3.3.2,任务控制链表,空任务控制块链表,-,未被分配(空白)的,TCB,链表,OSTCBFreeList,当进行系统初始化时,初始化函数会按用户提供的任务数为系统创建具有相应数量的任务控制块并把它们链接为一个链表。,由于这些任务控制块还没有对应的任务,故这个链表叫做,空任务块链表,。即相当于是一些空白的身份证。,应用程序调用,OSTaskCreate,(),创建一个任务时,该函数会调用系统函数,OSTCBInit,(),来为任务控制块进行初始化。首先为被创建任务从空任务控制块链表获取一个任务控制块,然后用任务的属性对任务控制块各个成员进行赋值,最后再把该任务控制块链入到任务控制块链表的头部。,任务控制块链表,OSTCBList,3.3.2,任务控制链表,任务控制块链表,空任务控制块链表,3.3.2,任务控制链表,uC,/OS-II,中提供了系统函数,OSTaskDel,(),,用于删除一个任务,-,实质就是将该任务的,TCB,从“,任务控制块列表,”移到了“,空任务控制块列表,”;,“,任务控制块,”,就相当于是一个任务的身份证,没有任务控制块的任务是不能被系统承认和管理。,3.3.2,任务控制链表,任务控制块链表其他相关系统管理变量,OSTCBPrioTbl,:,OS_TCB*,数据类型的数组,以,Prio,为下标存放已使能的,TCB,指针。用于加速,TCB,的访问。,OSTCBCur,:全局系统变量,指向当前正在运行的任务的,TCB,。,OSTCBFreeList,、,OSTCBList,OSTCBTbl,-,OSInit,(),建立的任务控制块数组,OSTCBPrioTbl,-,任务控制块优先级数组,3.3.3,任务控制块的初始化,任务控制块链表其他相关系统管理变量,INT8U,OS_TCBInit,(,INT8U,prio,/,优先级,存于,OSTCBPrio,中,OS_STK*,ptos,/,栈顶指针,存于,OSTCBStkPrt,中,OS_STK*,pbos,/,栈底指针,存于,OSTCBStkBottom,中,INT16U id,/,任务标识符,存于,OSTCBId,中,INT32U,stk_size,/,堆栈长度,存于,OSTCBStkSize,中,void*,pext,/,控制块扩展指针,存于,OSTCBExtPtr,中,INT16U opt,/,控制块选择项,存于,OSTCBOPt,中,),为被创建任务从空任务控制块中获取一个任务控制块;,用任务的属性对任务控制块各成员进行赋值;,把该任务控制块链接到任务控制链表中,3.4,任务就绪表及任务调度,多任务,OS,-,的基本工作方式,简单地说,就是能用一个处理器,并发,(,注意不是同时,!),地运行多个程序的计算机管理系统。,并发,:由同一个处理器轮换地运行多个程序。或者说是由多个程序轮班地,占用,处理器这个资源。且在占用这个资源期间,并不一定能够把程序运行完毕。,处理器如何进行程序的,切换?,程序的切换,处理器是个傻瓜,,PC,让它干啥,它就干啥。,PC,是个指路器,它指向哪儿,处理器就去哪儿,哪个程序占有了,PC,,哪个程序就占有了处理器。,如何操作,PC,切换,:,PC,目标地址,系统是通过把待运行程序的地址赋予程序计数器,PC,来实现程序的切换的。,指令,:不同计算机类型的指令不同,数据传送指令,子程序返回指令(,由堆栈弹出,),中断、中断返回指令(,由堆栈弹出,),任务运行时与处理器之间的关系,任务代码,任务堆栈,内存,处理器,PC,SP,处理器通过两个指针寄存器(,PC,和,SP,),来与任务代码和任务堆栈建立联系并运行它,寄存器组,程序运行环境,运行环境包括了两部分:处理器中的运行环境和内存中的运行环境,多,任务时的,问题,任务代码,任务堆栈,内存,处理器,PC,SP,任务代码,任务堆栈,内存,任务代码,任务堆栈,内存,?,当有,多个任务时,处理器中的运行环境应该怎么办?,寄存器组,程序运行环境,多任务时任务与处理器之间关系的,处理,程序,虚拟,处理器,PC,SP,虚拟,处理器,PC,SP,虚拟,处理器,PC,SP,虚拟,处理器,PC,SP,调度器,程序,处理器,PC,SP,在内存中为每个任务创建一个虚拟的处理器(处理器部分的运行环境,由操作系统的,调度器,按某种规则来进行这两个复制工作,复制,当需要运行某个任务时就把该任务的虚拟处理器复制到实际处理器中,复制,当需要中止当前任务时,则把任务对应的虚拟处理器复制到内存,复制,再把另一个需要运行的任务的虚拟处理器复制到实际处理器中,寄存器组,寄存器组,也就是说,任务的切换是,任务,运行环境的切换,虚拟处理器,虚拟处理器应该存储的主要信息:,程序的断点地址(,PC,),任务堆栈指针(,SP,),程序状态字寄存器(,PSW,),通用寄存器内容,函数调用信息(已存在于堆栈),这些内容通常保存在任务堆栈中,这些内容也常叫做任务的上下文。,程序切换的关键是把程序的,私有堆栈指针,赋予处理器的堆栈指针,SP,;实质上系统是通过,SP,的切换来实现程序的切换的。,虚拟处理器,要建立一个概念:,具有控制块的程序才是一个可以被系统所运行的任务。,程序代码、私有堆栈、任务控制块,是任务的三要件。,任务控制块提供了运行环境的存储位置。,调度,多任务操作系统的核心工作就是任务调度。,所谓,调度,,就是通过一个算法在多个任务中确定该运行的任务,做这项工作的函数就叫做,调度器,。,C,/OS_II,进行任务调度的思想是“近似地每时每刻总是让优先级最高的就绪任务处于运行状态”。为了保证这一点,它在系统或用户任务调用系统函数及执行中断服务程序结束时总是调用调度器,来确定应该运行的任务并运行它。,C,/OS_II,进行任务调度的依据就是,任务就绪表,3.4.1,任务就绪表的结构,为能够使系统清楚地知道,系统中哪些任务已经就绪,哪些还没有就绪,,C,/OS_II,在,RAM,中设立了一个记录表,,系统中的每个任务都在这个表中占据一,Bit,的位置,并用这个位置的状态(,1,或者,0,)来表示任务是否处于就绪状态,,这个表就叫做任务就绪状态表,简称叫,任务就绪表,-,一个,INT8U,的数组,OSRdyTbl,充当,最多,8,个元素,可以标示,64,个任务。,3.4.1,任务就绪表的结构,就绪表:,INT8,类型的二维数组,OSRdyTb1,;,以任务优先级别进行标识;,为,1,表示对应任务处于就绪状态;,8,个任务可看成一个任务组;,3.4.1,任务就绪表的结构,为加快访问任务就绪表的速度,系统定义了一个变量,OSRdyGrp,来表明就绪表每行中是否存在就绪任务,3.4.1,任务就绪表的结构,任务就绪表的示意图,3.4.1,任务就绪表的结构,任务优先级数据结构分析,uC,/OS-II,最多管理,64,个任务,,Prio,值域:,0 63,,对应的二进制数,000,000,111,111,(,6bit,),,OSRdyGrp,(任务组就绪变量),8 bit,,,任务就绪数组元素,OSRdyTbl,也是,8bit,。,prio.D5:3,-,对应,OSRdyTbl,的下标(任务组号,y,),也对应,OSRdyGrp,的位号。,prio.D2:0,-,对应,OSRdyTbl,元素的位号(任务组号,x,),备注:这就是,prio,的值和任务就绪表的映射关系。,3.4.1,任务就绪表的结构,举例,:,prio,=29,的任务在任务就续表中的表示。,29,的二进制表示为:,00,011,101,3(y),5(x),3.4.1,任务就绪表的结构,举例,:,prio,=29,的任务在任务就续表中的表示。,29,的二进制表示为:,00,011,101,3(y),5(x),3.4.2,任务就绪表的操作,任务就绪表的操作有:登记、注销和最高优先级查找。,依照,prio,“,置,/,清”任务就绪表的操作,在,uC,/OS-II,中预定义了一个,OSMapTbl,数组,以加快运算速度:,OSMapTbl0=0000,000,1,B,OSMapTbl1=0000,00,1,0B,OSMapTbl2=0000,0,1,00B,OSMapTbl3=0000,1,000B,OSMapTbl4=000,1,0000B,OSMapTbl5=00,1,0,0000B,OSMapTbl6=0,1,00,0000B,OSMapTbl7=,1,000,0000B,3.4.2,任务就绪表的操作,举例,:,prio,=29,的任务在任务就续表中的表示。,29,的二进制表示为:,00,011,101,3(y),5(x),3.4.2,任务就绪表的操作,在程序中,可以用下面的代码把优先级别为,prio,的任务置为就绪状态:,OSRdyGrp,|=,OSMapTblprio,3;,OSRdyTblprio,3|=OSMapTblprio,使用如下代码可使一个优先级别为,prio,的任务脱离就绪状态:,if(,(,OSRdyTblprio,3&=,OSMapTblprio&0 x07,),=0),OSRdyGrp,&=,OSMapTblprio,3;,3.4.2,任务就绪表的操作,最高优先级就绪任务的查找,从就绪表,(,OSRdyGrp,、,OSRdyTbl,),的当前状态(位图)到,最高优先级别,prio,的(任务)映射操作。,在,uC,/OS-II,中预定义了一个,OSUnMapTbl,数组,3.4.2,任务就绪表的操作,INT8UconstOSUnMapTbl256=0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x00to0 x0F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x10to0 x1F,*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x20to0 x2F,*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x30to0 x3F*/6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x40to0 x4F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x50to0 x5F*/,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x60to0 x6F,*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x70to0 x7F*/7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x80to0 x8F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x90to0 x9F*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xA0to0 xAF,*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xB0to0 xBF*/6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xC0to0 xCF*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xD0to0 xDF*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xE0to0 xEF*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0/*0 xF0to0 xFF*/;,3.4.2,任务就绪表的操作,在就绪表中查找最高优先级别任务的过程,说明:在“按图索骥”算法中,对于所有的任务其“索骥”时间都是一致的。,S1,、以系统变量,OSRdyGrp,为下标,查,OSUnMapTbl,表,可得,y,。,S2,、以,OSRdyTbl,的第,y,元素为下标,查,OSUnMapTbl,表,可得,x,。,40,96,Prio,=8*,y+x,3.4.2,任务就绪表的操作,用下代码可从任务就绪表中获取优先级别最高的就绪任务(,prio,):,y=,OSUnMapTal,OSRdyGrp,;,/,prio,的,D5,、,D4,、,D3,位,x=,OSUnMapTal,OSRdyTbly,;,/,prio,的,D2,、,D1,、,D0,位,prio,=(y3)+x,;,/,优先级别,或,y=,OSUnMapTbl,OSRdyGrp,;,prio,=(INT8U)(y 3)+,OSUnMapTbl,OSRdyTbly,);,3.4.3,任务的调度,任务控制块链表其他相关系统管理变量,OSTCBPrioTbl,:,OS_TCB*,数据类型的数组,以,Prio,为下标存放的,TCB,指针。用于加速,TCB,的访问。,3.4.3,任务的调度,任务控制块链表其他相关系统管理变量,OSTCBCur,:全局系统变量,指向当前正在运行的任务的,TCB,。,3.4.3,任务的调度,任务切换,-CPU,从运行某一任务转换到运行另一任务的过程。,任务调度,-,按照某规则进行任务切换的工作过程。,uC,/OS-II,中的任务切换由“,任务调度器,”完成。,任务调度器的两项主要工作,:,从任务就绪表中查找优先级最高的就绪任务,实现任务切换,uC,/OS-II,中有两个“任务调度器”:,任务级的调度器,OS_Sched,(),中断级的调度器,OSIntCtxSw,(),3.4.3,任务的调度,获得待运行任务,TCB,的指针,获得了最高优先权就绪任务的“优先级”后(存放在全局系统变量,OSPrioHighRdy,),用下指令即可获取该任务的,TCB,:,OSTCBHighRdy,=,OSTCBPrioTbl,OSPrioHighRdy,备注:,OSTCBPrioTbl,是以优先权为下标的“任务指针数组”,3.4.3,任务的调度,获得待运行任务,TCB,的指针,任务控制块(,TCB,)的结构,任务控制块结构的主要成员,typedef,struct,os_tcb,struct,os_tcb,*,OSTCBNext,;,/,指向下一个,TCB,的指针,struct,os_tcb,*,OSTCBPrev,;,/,指向前一个,TCB,的指针,OS_STK *,OSTCBStkPtr,;,/,指向任务堆栈栈顶的指针,INT16U,OSTCBDly,;,/,任务等待时间,INT8U,OSTCBStat,;,/,任务的当前状态标志,INT8U,OSTCBPrio,;,/,任务的优先级别,OS_TCB,;,3.4.3,任务的调度,-,任务调度,OS_Sched,(),void,OS_Sched,(void)#if OS_CRITICAL_METHOD=3,/*Allocate storage for CPU status register*/,OS_CPU_SR,cpu_sr,;#,endif,INT8U y;OS_ENTER_CRITICAL();,/*,所有代码都属于临界代码,在寻找进入就绪态的优先级最高的任务过程中,为防止中断服务程序把一个或几个任务的就绪位置位,中断要关掉*,/,if(,OSIntNesting,=0)&(,OSLockNesting,=0),/*,Sched,.only if all,ISRs,done¬ locked*/,y=,OSUnMapTblOSRdyGrp,;,/*Get pointer to HPT ready to run*/,OSPrioHighRdy,=(INT8U)(y 3)+,OSUnMapTblOSRdyTbly,);if(,OSPrioHighRdy,!=,OSPrioCur,),/*No,Ctx,Sw,if current task is highest,rdy,*/,OSTCBHighRdy,=,OSTCBPrioTblOSPrioHighRdy,;/,获取,TCB,控制块,OSCtxSwCtr,+;,/*Increment context switch counter*/,OS_TASK_SW();,/*,宏调用,完成实际上的任务切换,*/,OS_EXIT_CRITICAL();,3.4.3,任务的调度,-,任务调度,OS_Sched,(),说明:,OSIntNesting,=0&,OSLockNesting,=0,只有不是在中断服务子程序中且调度是允许时,才可以进行,OS_Sched,调度。,y=,OSUnMapTblOSRdyGrp,;,OSPrioHighRdy,=(INT8U)(y,已就绪最高优先级号,(,整数型,),OSPrioCur,-,当前任务优先级号,(,整数型,),3.4.3,任务的调度,-,任务调度,OS_Sched,(),说明:,OSTCBPrioTbl,-,数组元素为指向,OS_TCB,类型指针,数组的下标号为,TCB,相应任务的优先级号,OSTCBHighRdy,-,指向已就绪的最高优先级任务的,TCB,指针,OSCtxSwCtr,任务切换次数计数器。目的是让用户知道每秒做了多少次任务切换。用户需每秒将,OSCtxSwCtr,的值存入另一个变量,然后将,OSCtxSwCtr,清,0,。,OS_TASK_SW(),宏调用,完成实际上的任务切换。,3.4.3,任务的调度,2.,任务切换宏,OS_TASK_SW(),完成当前任务到待运行任务的切换,几个概念:,断点,-,当前任务被终止运行的位置。,断点数据,-,断点处,CPU,的,PC,、,SP,、,PSW,以及通用寄存器,(R0,R12),的当前数据。,程序“无缝”接续运行要求断点和断点数据(现场)的完全保护和恢复。,
展开阅读全文