资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第五章 任务管理,任务管理的任务,就绪任务及就绪表的概念,就绪表的操作,任务的创建,任务的删除,任务管理的其他函数,5.1,就绪任务管理,就绪表及作用,内核在进行任务调度时,必须知道哪个任务在运行、哪个任务是就绪的最高优先级的任务。实时任务调度的关键在于速度,要求无论系统的运行情况如何,调度的时间是确定的,不能把时间都用在调度上。因此就需要设计高效的多任务调度方法。查找高优先级的任务,与正在运行的任务的优先级进行比较以确定是否进行任务切换是内核在每个时钟中断都需要做的事情。为满足这样的需要,,C/OS-II,的开发者采用了就绪表,5.1.1,就绪任务表的结构,就绪任务表:实质是是一个,INT8U,类型的数组,OSRdyTble,INT8U OSRdyTblOS_RDY_TBL_SIZE;,7 6 5 4 3 2 1 0,15 14 13 12 11 10 9 8,23 22 21 20 19 18 17 16,31 30 29 28 27 26 25 24,OSRdyTbl0,OSRdyTbl1,OSRdyTbl2,OSRdyTbl3,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,图,5-1,一个可以记录,32,个任务就绪状态的任务就绪表,优先级别(任务的标识),1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,就绪组,:OSRdyGrp,是就绪组,类型是,INT8U,,,INT8U,等同于无符号的字符型,也就是,8,位无符号数。,OSRdyTbl,就是每个元素都为,8,位无符号数的数组,数组中元素的个数是,OS_RDY_TBL_SIZE,。,INT8U OSRdyGrp;,任务优先级和就绪表的关系,如何根据优先级来确定在就绪表中的位置,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,图,5-4,任务的优先级别与就绪表中,x,和,y,的关系,y,x,任务的优先级别,prio,1/0 1/0 1/0 1/0 1/01/0,例,5-1,已知一个已就绪的任务的优先级是,prio=35,试判断应在就绪表中的哪一位为,1,解:,35,的二进制是,00100100,,低三位是,100,,是,4,,所以在,OSRdyTble3,D5D4D3,是,100,,是,4,,所以在,OSRdyGrp,第三位是,1,,这样就找到了对应优先级所在的位置。,5.1.2,就绪表的操作,对就绪表需要做三项工作,1.,在就绪表中登记就绪任务,OSRdyGrp|=OSMapTblprio3;,OSRdyTblprio3|=OSMapTblprio&0 x07,为了加速确定位置定义了,查找表,OSMapTble,数组,INT8U const OSMapTbl=0 x01,0 x02,0 x04,0 x08,0 x10,0 x20,0 x40,0 x80;,第二种表达方式,第一种表达方式,OSRdyGrp,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,1,1,1,1,0,0,0,0,prio=29,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,1,D,7,D,6,D,5,D,4,D,3,D,2,D,1,D,0,1,OSRdyTbl3,图,5-5,把,prio,为,29,的任务置为就绪状态,Y,X,OSRdyGrp|=OSMapTblprio3;,OSRdyTblprio3,|=OSMapTblprio,2,从就绪表删除任务,if(OSRdyTblprio3&=,OSMapTblprio&0 x07)=0),OSRdyGrp&=,OSMapTblprio3;,3,从就绪表中获取优先级别最高的就绪任务,在调度时候,需要找到在就绪表中优先级最高的任务,实现的代码如下,INT8U const OSUnMapTbl=,/0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x00 to 0 x0F*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x10 to 0 x1F*/,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x20 to 0 x2F*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x30 to 0 x3F*/,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x40 to 0 x4F*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x50 to 0 x5F*/,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x60 to 0 x6F*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x70 to 0 x7F*/,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x80 to 0 x8F*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 x90 to 0 x9F*/,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xA0 to 0 xAF*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xB0 to 0 xBF*/,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xC0 to 0 xCF*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xD0 to 0 xDF*/,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0 xE0 to 0 xEF*/,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0/*0 xF0 to 0 xFF*/,;,y=OSUnMapTblOSRdyGrp;,x=OSUnMapTblOSRdyTbly;,prio=(y 3)+x;,算出最高优先级,最小内核,|,C/OS-II,微小内核分析,任务就绪表,OSRdyGrp,为,0 x69,,以此值为偏移量查表,3,、查找就绪态优先级最高的任务,找出最高优先级任务的横坐标,找出最高优先级任务的纵坐标,OSRdyTb10,为,0 x30,,以此值为偏移量查表,就绪任务组优先级最高的就是,4,(,010),x=0;,y+=2;,PC_DispChar(x,y,/,显示字符的位置,*,(char*)pdata,DISP_BGND_BLACK+DISP_FGND_WHITE);,x+=1;,/,如果按下,Esc,键则退出,uCOS_II,if(PC_GetKey(&key)=TRUE),if(key=0 x1B),PC_DOSReturn();,OSTimeDlyHMSM(0,0,1,0);/,等待,图5-8 例5-2应用程序运行结果,5.3,任务的挂起和恢复,任务的挂起,由于某种原因由任务资金或者其他任务停止这个任务的运行,放弃对,CPU,的控制权,OSTaskSuspend(),INT8U OSTaskSuspend(INT8U prio),就绪状态,运行状态,等待状态,图,5-9,任务的挂起(等待)和恢复,任务的,CPU,使用权被剥夺,OSTaskSuspend(),OSTaskResume(),OS_TASK_SW(),prio=0 xFF,?,标志,self=FALSE,并取任务,TCB,的指针,进入,Yes,No,prio,是空闲任务,?,返回,OS_TASK_SUSPEND_IDLE,Yes,No,标志,self=TRUE,并取任务,TCB,的指针,调用任务调度器,OS_Sched(),返回,OS_NO_ERR,图,5-10,函数,OSTaskSuspend(),的流程图,prio,是合法优先级别,?,返回,OS_PRIO_INVALID,Yes,No,指针非空?,返回,OS_TASK_SUSPEND_PRIO,Yes,No,Yes,取消任务的就绪状态,并在控制块中进行记录,标志,self=TRUE,?,Yes,No,恢复任务,恢复任务的函数,OSTaskResume(),INT8U OSTaskResume(INT8U prio),并取任务,TCB,的指针,进入,Yes,调用任务调度器,OS_Sched(),返回,OS_NO_ERR,图,5-11,函数,OSTaskResume(),的流程图,prio,是合法优先级别,?,返回,OS_PRIO_INVALID,Yes,No,指针,!=NULL,?,返回,OS_TASK_RESUME_PRIO,No,Yes,取消任务在控制块中,的挂起记录,任务存在,&,被挂起的,&,等待时间为,0?,No,返回,OS_TASK_NOT_SUSPEND,5.4,其他任务管理函数,5.4.1,任务优先级的修改,INT8U OSTaskChangePrio(,INT8U oldprio,INT8U newprio,);,任务的删除,INT8U OSTaskDel(,INT8U prio,),INT8U OSTaskDelReq(,INT8U prio,),prio=OS_PRIO_SELF,?,返回被删除任务,TCB,的成员,OSTCBDelReq,的值,进入,Yes,No,prio,是空闲任务,?,返回,OS_TASK_IDLE_PRIO,Yes,No,返回,OS_NO_ERR,图,5-12,函数,OSTaskDelReq(),的流程图,prio,是合法优先级别,?,返回,OS_PRIO_INVALID,Yes,No,prio,任务的,TCB,不存在?,置,prio,任务,TCB,的,OSTCBDelReq,的值,为,OS_TASK_DEL_REQ,No,Yes,返回,OS_TASK_NOT_EXIST,提出删除请求任务的执行路径,被删除任务的执行路径,void TaskA(,void*pdata,),OSTaskDel Req(3);,void TaskB(,void*pdata,),if(OSTaskDel Req(OS_PRIO_SELF),=OS_TASK_DEL_REQ),OSTaskDel(OS_PRIO_SELF);,OSTCBDelReq,OS_TASK_DEL_REQ,任务B的TCB,设置,查询,图5-13 函数OSTaskDel Req在请求删除任务方和被删除任务方的作用,5.4.3,查询任务的信息,INT8U OSTaskQuery(,INT8U prio,OS_TCB*pdata,),5.5,任务管理总结,任务管理的核心内容,首先是数据结构,包括任务控制块、空闲链表和就绪链表、任务优先级指针表、任务堆栈、任务就绪表和就绪组,以及其他的全局变量。这些数据结构是在做操作系统移植及使用中必须要掌握的,也是读懂操作系统代码的基础。,接下来就是任务控制块的初始化。任务控制块包含了任务的相关信息。在创建任务时,分配一个任务控制块,对其进行初始化工作。学习任务控制块的初始化函数,还可以更深入地了解任务控制块。在这里还涉及了就绪表和就绪组,以及对空闲链表和就绪链表的操作。,思考题,1,任务控制块是一个什么样的数据结构?请用,C,语言定义一个任务控制块数组,并对其进行初始化。,2,论述任务控制块初始化过程中构建任务控制块空闲链表的过程。,3,就绪表和就绪组的用途是什么?论述它们之间的关系。,4,编写代码实现将优先级为,13,、,23,、,33,的任务就绪,然后取消优先级为,25,的任务的就绪标志。,5,使用,C,语言创建一个任务堆栈,将这个堆栈赋值给一个任务控制块。,6,论述任务堆栈的增长方向对入栈出栈操作的影响。,7,解析任务调度的过程。,8,任务创建函数,OSTaskCreate,和,OSTaskCreateEXT,有哪些区别?,9,任务是如何挂起和恢复的?,10,为什么要请求删除任务而不直接删除?请求删除任务函数有哪些功能?流程是什么?,11,论述统计任务是如何进行,CPU,利用率统计的。,
展开阅读全文