您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 5.Task-Management-and-Scheduling(2)
1实时嵌入式操作系统艾云峰aiyunfeng@gmail.comCollegeofComputing&CommunicationEngineeringReal-timeEmbeddedOperatingSystem2上节内容回顾任务控制块-TCB一个数据结构,重要结构变量就绪表内核用于维护处于就绪状态的任务的两个表格就绪表的几种操作两个数组和两个链表OSTCBTbl[]与OSTCBFreeListOSTCBPrioTbl[]与OSTCBList任务控制块的初始化申请空闲任务控制块,加入OSTCBList链表设置任务处于就绪状态调度函数OSSched()OS_TASK_SW()UCOS的初始化和多任务启动时钟滴答服务程序3本节主要内容1.UC/OS-II的任务管理2.UC/OS-II的时间管理4UC/OS-II的任务管理提纲建立任务任务堆栈删除任务请求删除任务改变任务的优先级挂起任务恢复任务获得任务的信息5建立任务(1)-概述想让μC/OS-Ⅱ管理用户的任务,用户必须要先建立任务任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立注意:在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务任务不能由中断服务程序(ISR)来建立建立任务的两个函数:OSTaskCreate()OSTaskCreateExt()6建立任务(2)-OSTaskCreate()实现先检测分配给任务的优先级是否有效任务的优先级必须在0到OS_LOWSEST_PRIO之间判断在规定的优先级上是否已经建立任务放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级;这就使得OSTaskCreate()在设置任数据结构的其他部分时能重新允许中断OSTCBInit()成功,增加OSTaskCtrOSTaskCtr用于保存产生的任务数目如果OSTCBInit()返回失败,就置OSTCBPrioTbl[prio]的入口为0以放弃该任务的优先级如果OSTaskCreate()函数是在某个任务的执行过程中被调用则任务调度函数会被调用来判断是否新建立的任务比原来的任务有更高的优先级;果新任务的优先级更高,内核会进行一次从旧任务到新任务的任务切换7任务堆栈(1)-任务堆栈的分配每个任务都有自己的堆栈空间。堆栈必须声明为OS_STK类型,并且由连续的内存空间组成用户可以静态分配堆栈空间(在编译的时候分配)也可以动态地分配堆栈空间(在运行的时候分配)静态堆栈声明如程序:staticOS_STKMyTaskStack[stack_size];OS_STKMyTaskStack[stack_size];用C编译器提供的malloc()函数来动态地分配堆栈空间8任务堆栈(2)-任务堆栈的方向μC/OS-Ⅱ支持的处理器的堆栈既可以从上(高地址)往下(低地址)长也可以从下往上长用户在调用OSTaskCreate()或OSTaskCreateExt()的时候必须知道堆栈是怎样长的,因为用户必须得把堆栈的栈顶传递给以上两个函数当OS_CPU.H文件中的OS_STK_GROWTH置为0时,用户需要将堆栈的最低内存地址传递给任务创建函数当OS_CPU.H文件中的OS_STK_GROWTH置为1(高-低)时,用户需要将堆栈的最高内存地址传递给任务创建函数9任务堆栈(3)-增强应用代码的可移植性对两个方向增长的堆栈都提供支持的代码(需要配置)10删除任务(1)–概述删除任务,是说任务将返回并处于休眠状态,并不是说任务的代码被删除了,只是任务的代码不再被μC/OS-Ⅱ调用任务的删除意味着它的任务控制块从OSTCBList链表中移到OSTCBFreeList时钟节拍函数中就不会处理它了,这样调度把它置入就绪表的可能性就没了如果它已经处于就绪表中,那么它将被移出这样调度器函数就不会处理它,这样它被调度运行的机会就没了如果任务处于邮箱、消息队列、信号量的等代表中,也要把它移出等待表11删除任务(2)-OSTaskDel()OSTaskDel()INT8UOSTaskDel(INT8Uprio);参数:prio为指定要删除任务的优先级也可以用参数OS_PRIO_SELF(0xFF)代替,删除后,下一个优先级最高的就绪任务将开始运行返回值:OS_NO_ERR:函数调用成功。OS_TASK_DEL_IDLE:错误操作,试图删除空闲任务(Idletask)。OS_TASK_DEL_ERR:错误操作,指定要删除的任务不存在。OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO。OS_TASK_DEL_ISR:错误操作,试图在中断处理程序中删除任务。注意/警告OSTaskDel()将判断用户是否试图删除uC/OS中的空闲任务(Idletask)。在删除占用系统资源的任务时要小心,此时,为安全起见可以用另一个函数OSTaskDelReq()。12删除任务(3)-OSTaskDel()确保用户所要删除的任务并非是空闲任务用户可以删除statistic任务确保用户不是在ISR例程中去试图删除一个任务指定OS_PRIO_SELF参数来删除自己13删除任务(4)-OSTaskDel()如果任务处于就绪表中,它会直接被移除如果任务处于邮箱、消息队列或信号量的等待表中,它就从自己所处的表中被移除重新允许中断以减少中断的响应时间。这样,OSTaskDel()就能处理中断服务了,但由于它增加了OSLockNesting,ISR执行完后会返回到被中断任务,从而继续任务的删除工作确保处理器在中断允许的情况下至少执行一个指令在OSTaskDel()重新关中断后,它通过锁定嵌套计数器(OSLockNesting)减一以重新允许任务调度OSTaskDel()调用用户自定义的OSTaskDelHook()函数减少μCOS-Ⅱ的任务计数器14OSTaskDel()将被删除的任务的OS_TCB从OS_TCB双向链表中移除;没有必要检验ptcb-OSTCBNext==0的情况,因为OSTaskDel()不能删除空闲任务,而空闲任务就处于链表的末端(ptcb-OSTCBNext==0)简单地将指向被删除的任务的OS_TCB的指针指向NULL,从而达到将OS_TCB从优先级表中移除的目的删除任务(5)-OSTaskDel()OS_TCB返回到空闲OS_TCB表中,并允许其它任务的建立调用任务调度程序来查看在OSTaskDel()重新允许中断的时候,中断服务子程序是否曾使更高优先级的任务处于就绪状态15请求删除任务(1)-概述如果任务A拥有内存缓冲区或信号量之类的资源,而任务B想删除该任务,这些资源就可能由于没被释放而丢失在这种情况下,用户可以想法子让拥有这些资源的任务在使用完资源后,先释放资源,再删除自己用户可以通过OSTaskDelReq()函数来完成该功能发出删除任务请求的任务(任务B)和要删除的任务(任务A)都需要调用OSTaskDelReq()函数具体实现见下页ppt16请求删除任务(2)-例子:B提出对A的删除请求任务B需要决定在怎样的情况下请求删除任务如果任务需要被删除,可以通过传递被删除任务的优先级来调用OSTaskDelReq()如果要被删除的任务不存在(即任务已被删除或是还没被建立),OSTaskDelReq()返回OS_TASK_NOT_EXIST;如果OSTaskDelReq()的返回值为OS_NO_ERR,则表明请求已被接受但任务还没被删除;当任务A完全删除自己后,0S_TASK_NOT_EXIST,此时循环结束17请求删除任务(3)-例子:A收到删除请求后,删除自己在OS_TCB中存有一个标志,任务通过查询这个标志的值来确认自己是否需要被删除;这个标志的值是通过调用OSTaskDelReq(OS_PRIO_SELF)而得到的;当OSTaskDelReq()返回给调用者OS_TASK_DEL_REQ时,则表明已经有另外的任务请求该任务被删除了被删除的任务会释放它所拥有的所用资源;并且调用OSTaskDel(OS_PRIO_SELF)来删除自己18请求删除任务(4)-OSTaskDelReq()如果正在删除的任务是空闲任务,OSTaskDelReq()会报错并返回它要保证调用者请求删除的任务的优先级是有效的如果调用者就是被删除任务本身,存储在OS_TCB中的标志将会作为返回值如果用户用优先级而不是OS_PRIO_SELF指定任务,并且任务是存在的,OSTaskDelReq()就会设置任务的内部标志如果任务不存在,OSTaskDelReq()则会返回OS_TASK_NOT_EXIST,表明任务可能已经删除自己了19改变任务的优先级(1)-OSTaskChangePrio()功能:改变其它任务的优先级改变任务本身的优先级:第一个参数OS_PRIO_SELF函数说明INT8UOSTaskChangePrio(INT8Uoldprio,INT8Unewprio);参数oldprio是任务原先的优先级newprio是任务的新优先级返回值OS_NO_ERR:任务优先级成功改变OS_PRO_INVALID:参数中的任务原先优先级或新优先级大于或等于OS_LOWEST_PRIOOS_PRIO_EXIST:参数中的新优先级已经存在OS_PRIO_ERR:参数中的任务原先优先级不存在20改变任务的优先级(2)-执行循序函数执行流程判断参数中的任务原先优先级或新优先级是否大于或等于OS_LOWEST_PRIO判断参数中的新优先级是否已经存在判断参数中的任务原先优先级是否存在如果任务目前的状态是Ready--改变优先级后仍设为ready状态Waiting--改变优先级后仍设为waiting状态全局变量的改变令OSTCBPrioTbl[oldprio]指向空指针令OSTCBPrioTbl[newprio]指向原任务控制块改变任务控制块的内容重新调度21改变任务的优先级(3)-实现μC/OS-Ⅱ不允许多个任务具有相同的优先级,所以OSTaskChangePrio()需要检验新优先级是否是合法的(即不存在具有新优先级的任务)μC/OS-Ⅱ通过将某些东西储存到OSTCBPrioTbl[newprio]中保留这个优先级;如此就使得OSTaskChangePrio()可以重新允许中断,因为此时其它任务已经不可能建立拥有该优先级的任务,也不能通过指定相同的新优先级来调用OSTaskChangePrio()。预先计算新优先级任务的OS_TCB中的某些值;而这些值用来将任务放入就绪表或从该表中移除检查想要改变优先级的任务是否存在22如果任务已经就绪,它可能会正在等待一个信号量、一封邮件或是一个消息队列。如果OSTCBEventPtr非空(不等于NULL),OSTaskChangePrio()就会知道任务正在等待以上的某件事。如果任务在等待某一事件的发生,OSTaskChangePrio()必须将任务从事件控制块(参看6.00,事件控制块)的等待队列(在旧的优先级下)中移除。并在新的优先级下将事件插入到等待队列中检验一下OSTaskChangePrio()想要改变优先级的任务是否就绪。如果该任务处于就绪状态,它必须在当前的优先级下从就绪表中移除,然后在新的优先级下插入到就绪表中通过插入NULL指针将指向当前任务OS_TCB的指针从优先级表中移除。这使得当前任务的旧的优先级可以重新使用了改变任务的优先级(4)-实现将指向任务OS_TCB的指针存到OSTCBPrioTbl[]中OSTaskChangePrio()完成了关键性的步骤后,在新的优先级高于旧的优先级或新的优先级高于调用本函数的任务的优先级情况下,任务调度程序就会被调用23挂起任务(1)-OSTaskSuspend()INT8UOSTaskSusp
本文标题:5.Task-Management-and-Scheduling(2)
链接地址:https://www.777doc.com/doc-6157955 .html