您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 3-2.UCOS-内核结构
1实时嵌入式操作系统艾云峰aiyunfeng@gmail.comCollegeofComputing&CommunicationEngineeringReal-timeEmbeddedOperatingSystem2UCOS-II任务管理与调度学习本节内容的主要目的了解UCOS-II是如何进行任务调度的了解UCOS-II和任务相关的初始化过程了解UCOS-II中断服务程序的编写方法3主要内容临界段操作;任务控制块;调度表;几个全局变量、链表、之间的关系;任务控制块的初始化;OS的初始化操作,OS的多任务启动;OS的调度;中断服务程序编写方法;时钟中断服务程序;4临界段(CriticalSections)定义回顾也称为临界区,指运行时不可分割的代码;即一旦这部分代码开始执行,则不允许任何中断打入为确保临界段代码的执行,在进入临界段之前要关中断,而临界段代码执行完以后要立即开中断。这样做可以避免同时有其它任务或中断服务进入临界段代码不同C编译器厂商选择不同的方法来处理关中断和开中断,为了便于移植,μC/OS-Ⅱ定义两个宏(macros)来关中断和开中断(OS_CPU.h)OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()5UC/OS-II中的任务(1)一个任务通常是一个无限的循环任务的定义形式voidYourTask(void*pdata){/*用户代码*/OSTaskDel(OS_PRIO_SELF);}一个任务看起来像其它C的函数一样,有函数返回类型,有形式参数变量,但是任务是绝不会返回参数的;任务可以自我删除;形式参数变量由用户创建任务时传入,允许用户应用程序传递任何类型的数据给任务也可以建立许多相同的任务,所有任务都使用同一个函数(或者说是同一个任务代码程序)6UC/OS-II中的任务(2)UC/OS-Ⅱ可以管理多达64个任务,作者保留了优先级为0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRIO-2,OS_LOWEST_PRIO-1以及OS_LOWEST_PRIO这8个任务以被将来使用,因此用户可以有多达56个应用任务#defineOS_LOWEST_PRIO63//OS_CFG.hUC/OS-II中必须给每个任务赋以不同的优先级,优先级可以从0到OS_LOWEST_PRIO-2。为了使μC/OS-Ⅱ能管理用户任务,用户必须在建立一个任务的时候,调用OSTaskCreat或OSTaskCreatExt()函数INT8UOSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT8Uprio)OSTaskCreateExt()是OSTaskCreate()的扩展,扩展了一些附加功能7UC/OS-II中任务的状态(1)8UC/OS-II中任务的状态(2)睡眠态(DORMANT)指任务驻留在程序空间之中,还没有交给μC/OS-Ⅱ管理,(把任务交给μC/OS-Ⅱ是通过调用下述两个函数之一:OSTaskCreate()或OSTaskCreateExt())。当任务一旦建立,这个任务就进入就绪态准备运行。任务的建立可以是在多任务运行开始之前,也可以是动态地被一个运行着的任务建立。如果一个任务是被另一个任务建立的,而这个任务的优先级高于建立它的那个任务,则这个刚刚建立的任务将立即得到CPU的控制权。一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。调用OSStart()可以启动多任务。OSStart()函数运行进入就绪态的优先级最高的任务。就绪的任务只有当所有优先级高于这个任务的任务转为等待状态,或者是被删除了,才能进入运行态。正在运行的任务可以通过调用两个函数之一将自身延迟一段时间,这两个函数是OSTimeDly()或OSTimeDlyHMSM()。这个任务于是进入等待状态,等待这段时间过去,下一个优先级最高的、并进入了就绪态的任务立刻被赋予了CPU的控制权。等待的时间过去以后,系统服务函数OSTimeTick()使延迟了的任务进入就绪态(见3.10节,时钟节拍)。正在运行的任务期待某一事件的发生时也要等待,手段是调用以下3个函数之一:OSSemPend(),OSMboxPend(),或OSQPend()。调用后任务进入了等待状态(WAITING)。当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。正在运行的任务是可以被中断的,除非该任务将中断关了,或者μC/OS-Ⅱ将中断关了。被中断了的任务就进入了中断服务态(ISR)。响应中断时,正在执行的任务被挂起,中断服务子程序控制了CPU的使用权。中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态。在这种情况下,从中断服务子程序返回之前,μC/OS-Ⅱ要判定,被中断的任务是否还是就绪态任务中优先级最高的。如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。当所有的任务都在等待事件发生或等待延迟时间结束,μC/OS-Ⅱ执行空闲任务(idletask),执行OSTaskIdle()函数。9任务控制块(TaskControlBlocks)描述:任务控制块是一个数据结构,当任务的CPU使用权被剥夺时,μC/OS-Ⅱ用它来保存该任务的状态;当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行任务控制块全部驻留在RAM中任务建立的时候,该任务的任务控制就被初始化了INT8UOS_TCBInit(INT8Uprio,OS_STK*ptos,OS_STK*pbos,INT16Uid,INT32Ustk_size,void*pext,INT16Uopt)注:UC/OS-II中系统函数的命名以OS开头的系统函数是提供给用户使用的系统函数以OS_开头的系统函数是uc/os中的内部函数,一般用户程序不会使用这些函数10任务控制块–基本描述(1)uCOS_II.htypedefstructos_tcb{OS_STK*OSTCBStkPtr;structos_tcb*OSTCBNext;structos_tcb*OSTCBPrev;INT16UOSTCBDly;INT8UOSTCBStat;INT8UOSTCBPrio;INT8UOSTCBX;INT8UOSTCBY;INT8UOSTCBBitX;INT8UOSTCBBitY;}OS_TCB;注:这是不完全定义,在以后部分中会逐步介绍其它成分11任务控制块–基本描述(2)OS_STK*OSTCBStkPtr;指向当前任务栈顶的指针,μC/OS-Ⅱ允许每个任务有自己的栈,尤为重要的是,每个任务的栈的容量可以是任意的structos_tcb*OSTCBNext;structos_tcb*OSTCBPrev;用于已建立任务的任务控制块OS_TCB的双向链表,该链表在时钟节拍函数OSTimeTick()中使用,用于刷新各个任务的任务延迟变量.OSTCBDly每个任务的任务控制块OS_TCB在任务建立的时候被链接到链表中,在任务删除的时候从链表中被删除INT16UOSTCBDly;调用两个延时函数之一时,这个变量保存的是任务延时或者允许等待事件发生的最多时钟节拍数12任务控制块–基本描述(3)INT8UOSTCBStat;任务的状态字。当OSTCBStat为0,任务进入就绪态#defineOS_STAT_RDY0x00/*Readytorun*/#defineOS_STAT_SEM0x01/*Pendingonsemaphore*/#defineOS_STAT_MBOX0x02/*Pendingonmailbox*/#defineOS_STAT_Q0x04/*Pendingonqueue*/#defineOS_STAT_SUSPEND0x08/*Taskissuspended*/#defineOS_STAT_MUTEX0x10/*Pendingonmutualexclusionsemaphore*/#defineOS_STAT_FLAG0x20/*Pendingoneventflaggroup*/INT8UOSTCBPrio;任务优先级。高优先级任务的OSTCBPrio值小13任务控制块–基本描述(4)INT8UOSTCBX;INT8UOSTCBY;INT8UOSTCBBitX;INT8UOSTCBBitY;用于加速任务进入就绪态的过程或进入等待事件发生状态的过程(避免在运行中去计算这些值)这些值是在任务建立时算好的,或者是在改变任务优先级时算出的算法清单:OSTCBY=priority3;OSTCBBitY=OSMapTbl[priority3];OSTCBX=priority&0x07;OSTCBBitX=OSMapTbl[priority&0x07];14就绪表(ReadyList)(1)作用:就绪表记录了每个任务是否处于就绪状态,每个任务的就绪态标志都放入就绪表中就绪表中有两个变量OSRdyGrp和OSRdyTbl[](UCOS_II.h)INT8UOSRdyGrp;INT8UOSRdyTbl[OS_RDY_TBL_SIZE];#defineOS_RDY_TBL_SIZE((OS_LOWEST_PRIO)/8+1)OSRdyGrp的每一位都对应一个包含8个任务的任务组;某任务组中的任何一个任务处于就绪状态时,都要把改任务组对应位置1若OS_LOWEST_PRIO=63,OSRdyTbl[]最多对应64个任务,某任务进入就绪状态时,都要把其在OSRdyTbl[]中的对应位置1就绪表OSRdyTbl[]数组的大小取决于OS_LOWEST_PRIO,当用户的应用程序中任务数目比较少时,减少OS_LOWEST_PRIO的值可以降低μC/OS-Ⅱ对RAM(数据空间)的需求量15就绪表(2)-任务与就绪表的关系OSRdyGrp是字节型变量,bit0对应的任务组包含优先级0~7的任务;bit1对应任务组包含优先级8~15的任务;依此类推。任务所在任务组在OSRdyGrp中的对应位是prio3(prio/8,商)任务prio在OSRdyTbl[]中的对应位是字节OSRdyTbl[prio3]的prio&0x07位(prio%8,余数)OSRdyTbl[]最多对应8个字节,其中字节OSRdyTbl[0]对应优先级是0~7的8个任务;OSRdyTbl[1]对应优先级是8~15的8个任务;依次类推;当OSRdyTbl[i]非0时,OSRdyGrp的第i位置116就绪表(3)-使任务进入就绪状态使优先级是prio的任务进入就绪状态可用如下方法OSRdyGrp|=OSMapTbl[prio3];OSRdyTbl[prio3]|=OSMapTbl[prio&0x07];其中OSMapTbl如下图所示:17就绪表(3)-从就绪表中删除一个任务当一个任务从就绪态转为其它状态时,应从就绪表中删除该任务对应的状态位,具体是将就绪任务表数组OSRdyTbl[]中相应元素的相应位清零对于OSRdyGrp,判断该任务所在任务组,如果全组任务没有一个是就绪态时,才将相应位清零假定某任务优先级是prio,从就绪表中删除该任务的算法if((OSRdyTbl[prio3]&=~OSMapTbl[prio&0x07])==0)OSRdyGrp&=~OSMapTbl[prio3];18就绪表(4)-查找就绪表中处于就绪状态的任务思路:为了找到那个进入就绪态的优先级最高的任务,并不需要从OSR
本文标题:3-2.UCOS-内核结构
链接地址:https://www.777doc.com/doc-4302795 .html