第2章 uCOS-II中的任务.ppt

上传人:文库蛋蛋多 文档编号:2636823 上传时间:2023-02-20 格式:PPT 页数:147 大小:6.97MB
返回 下载 相关 举报
第2章 uCOS-II中的任务.ppt_第1页
第1页 / 共147页
第2章 uCOS-II中的任务.ppt_第2页
第2页 / 共147页
第2章 uCOS-II中的任务.ppt_第3页
第3页 / 共147页
第2章 uCOS-II中的任务.ppt_第4页
第4页 / 共147页
第2章 uCOS-II中的任务.ppt_第5页
第5页 / 共147页
点击查看更多>>
资源描述

《第2章 uCOS-II中的任务.ppt》由会员分享,可在线阅读,更多相关《第2章 uCOS-II中的任务.ppt(147页珍藏版)》请在三一办公上搜索。

1、第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,1 任务的基本概念,任务概述任务状态系统任务,1)任务概述,从程序设计角度看,uC/OS-II中的任务是一个线程,其代码通常是一个无限循环结构/超循环结构,看起来像其它C函数一样。,void mytask(void*pdata)for(;)do something;waiting;do something;,从任务的存储结构看,任务由三个部分组成:任务控制块、任务代码与任务堆栈,1)任务

2、概述,1)任务概述,1)任务概述,C/OS II 支持64个任务,每个任务有一个特定的优先级。任务的优先级别用数字表示,0表示的任务的优先级最高,数字越大表示的优先级越低。通过常数OS_LOWEST_PRIO(在OS_CFG.H中)定义系统的最低优先级别,同时限定系统能容纳的最多任务数量。建议用户不要使用优先级为0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRIO-2、OS_LOWEST_PRIO-1、OS_LOWEST_PRIO-0的任务。最低的两个已被目前版本的系统占用,将来版本可能会用到其它的。,2)任务状态,睡眠态(DORMANT):任务驻留在程序空间,还没有

3、交给C/OS-管理,还没有配备任务控制块,还没有创建。把任务交给C/OS-是通过调用下述两个函数之一来完成的:OSTaskCreate()或OSTaskCreateExt()。就绪态(READY):任务一旦建立,就进入就绪态准备运行。一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。,2)任务状态,运行态(RUNNING):正在使用CPU的状态称运行态。就绪的任务只有当所有优先级高于自己的任务转为等待状态,或者是被删除了,才能进入运行态。等待态(WAITING):等待某事件发生的状态.正在运行的任务可以通过调用OSTimeDly()或OSTimeD

4、lyHMSM()进入等待状态调用OSSemPend()、OSMboxPend()或OSQPend()进入等待状态(WAITING)。,2)任务状态,中断服务态(ISR):正在运行的任务被中断(除非中断是关闭的)时就进入了中断服务态(ISR)。,2)任务状态,3)系统任务,空闲任务(Idle Task)C/OS-总要建立一个空闲任务,这个任务在没有其它任务进入就绪态时投入运行。这个空闲任务OSTaskIdle()永远设为最低优先级,即OS_LOWEST_PRI0。空闲任务OSTaskIdle()什么也不做,只是在不停地给一个32位的名叫OSIdleCtr的计数器加1,统计任务使用这个计数器以确定

5、现行应用软件实际消耗的CPU时间。空闲任务不可能被应用软件删除,3)系统任务,3)系统任务,统计任务OSTaskStat()任务OSTaskStat()是负责统计运行时间的任务,如果用户将系统定义常数OS_TASK_STAT_EN(见文件OS_CFG.H)设为1,这个任务就会建立。一旦得到允许,统计任务每秒运行一次(OS_CORE.C)以计算当前的CPU利用率。也即计算应用程序使用了多少CPU时间,用百分比表示,这个值放在一个有符号8位整数OSCPUsage中,精确度是1个百分点。,第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,

6、7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,2 任务堆栈,堆栈创建堆栈增长方向堆栈检验堆栈的初始化,2 任务堆栈-创建,1)堆栈创建堆栈是在存储器中按数据“后进先出(LIFO)的原则组织的连续存储空间。为满足任务切换和响应中断时保存CPU寄存器中的内容及任务私有数据的需要,每个任务都应该配有自己的堆栈。uC/OS-II中堆栈的数据类型为为OS_STK(typedef unsigned int OS_STK)。用户可以静态分配堆栈空间(在编译的时候分配)也可以动态地分配堆栈空间(在运行的时候分配)。,2 任务堆栈-创建,动态分配堆栈,静态分配

7、堆栈Static OS_STK MyTaskStackstack_size;或OS_STK MyTaskStackstack_size;,2 任务堆栈-增长方向,2)堆栈增长方向C/OS-支持的堆栈既可以向上增长(低地址往高地址)也可以向下增长。用户在调用OSTaskCreate()或OSTaskCreateExt()的时候必须知道堆栈是怎样增长的,因为用户必须得把堆栈的栈顶传递给以上两个函数,当堆栈向上增长时,将OS_STK_GROWTH置为0,需将堆栈的最低内存地址传递给任务创建函数。,2 任务堆栈-增长方向,当堆栈向下增长时,置OS_STK_GROWTH为1,需要将堆栈的最高内存地址传递

8、给任务创建函数,,堆栈向下增长(OS_STK_GROWTH=1),OSTaskCreate(task,pdata,对两个方向增长的堆栈都提供支持的代码,2 任务堆栈-增长方向,2 任务堆栈-检验,3)堆栈检验,OSTaskStkChk()有时候确定任务实际所需的堆栈空间大小是很有必要的。因为这样用户就可以避免为任务分配过多的堆栈空间,从而减少自己的应用程序代码所需的RAM(内存)数量。C/OS-提供的OSTaskStkChk()函数可以为用户提供这种有价值的信息。,Stack checking,OSTaskStkChk()顺着堆栈的栈底开始计算空闲的堆栈空间大小。任务所用的堆栈的空间大小等于O

9、STaskCreateExt()中定义的堆栈尺寸减去储存值为0的连续堆栈入口数目。,2 任务堆栈-检验,2 任务堆栈-检验,用户应该使自己的应用程序运行足够长的时间,并且经历最坏的堆栈使用情况,这样才能得到正确的数值。一旦OSTaskStkChk()提供给用户最坏情况下堆栈的需求,用户就可以重新设置堆栈的最后容量了。为了适应系统以后的升级和扩展,用户应该多分配10100的堆栈空间。在堆栈检验中,用户所得到的只是一个大致的堆栈使用情况,并不能说明堆栈使用的全部实际情况。,2 任务堆栈-初始化,4)任务堆栈的初始化当处理器启动一个任务时,处理器的各寄存器总是需要预置一些与待运行任务相关的初始数据,

10、如指向任务代码的指针、指向任务堆栈的指针、程序状态字PSW等,这些初始数据从何而来?系统在创建一个新任务时,应该把启动该任务所需的初始数据(指向任务代码的指针、指向任务堆栈的指针、程序状态字PSW等)事先存放到这个任务的堆栈中。任务堆栈初始化函数OSTaskStkInit()完成上述工作(其在OSTaskCreate()创建任务时被调用)。,2 任务堆栈-初始化,#if OS_VERSION=251OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16U opt)#elsevoid*OSTaskStkInit

11、(void(*task)(void*pd),void*pdata,void*ptos,INT16U opt)#endif unsigned int*stk;opt=opt;/*opt is not used,prevent warning*/stk=(unsigned int*)ptos;/*Load stack pointer*/,OSTaskStkInit(),2 任务堆栈-初始化,/*build a context for the new task*/*-stk=(unsigned int)task;/*pc*/*-stk=(unsigned int)task;/*lr*/*-stk=0

12、;/*r12*/*-stk=0;/*r11*/*-stk=0;/*r10*/*-stk=0;/*r9*/*-stk=0;/*r8*/*-stk=0;/*r7*/*-stk=0;/*r6*/,2 任务堆栈-初始化,*-stk=0;/*r5*/*-stk=0;/*r4*/*-stk=0;/*r3*/*-stk=0;/*r2*/*-stk=0;/*r1*/*-stk=(unsigned int)pdata;/*r0*/*-stk=(SVC32MODE|0 x0);/*cpsr IRQ,FIQ disable*/*-stk=(SVC32MODE|0 x0);/*spsr IRQ,FIQ disable

13、*/return(void*)stk);,第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,3 任务控制块,1)任务控制块结构2)任务控制块链表3)任务控制块初始化,1)任务控制块结构,任务控制块(Task Control Blocks,OS_TCBs)是C/OS-用来存储任务堆栈指针、当前状态、优先级及任务链表指针等一些与任务管理有关的属性的结构类型数据。任务控制块是任务的身份证,每个任务都有一个属于自已的任务控制块,当任务的CPU使

14、用权被剥夺时,任务的属性/环境被保存在任务控制块中,而当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。OS_TCBs全部驻留在RAM中。OS_TCBs 在任务建立的时候被初始化.,任务控制块结构成员,OSTCBStkPtr:指向当前任务堆栈栈顶的指针。OSTCBExtPtr:指向用户定义的任务控制块扩展的指针。用户可以扩展任务控制块而不必修改C/OS-的源代码,只在函数OstaskCreateExt()中使用,使用时将OS_TASK_CREAT_EN设为1.OSTCBStkBottom:指向任务堆栈栈底的指针。递减栈指针指向任务使用的栈空间的最低地址;

15、递增型栈则指向栈空间的最高地址。OSTaskStkChk()可用其检验栈空间的使用情况以确定任务实际需要的栈空间。在OSTaskCreateExt()函数中使用,即需将OS_TASK_CREATE_EXT_EN设为1。,任务控制块结构成员,OSTCBStkSize:堆栈尺寸。栈中可容纳的指针元数目/入口地址,不是用字节表示的栈容量总数。例 设栈中可以保存1,000个入口地址,则:若每个地址宽度为32位,实际栈容量是4,000字节。若每个地址宽度为16位,总栈容量是2,000字节。在OSStakChk()中调用,须将OS_TASK_CREAT_EXT_EN设为1。,任务控制块结构成员,OSTCB

16、Opt:OSTaskCreateExt()中的选项,C/OS-目前只支持3个选择项:OS_TASK_OTP_STK_CHK-STK检查OS_TASK_OPT_STK_CLR-清零OS_TASK_OPT_SAVE_FP-浮点运算,任务控制块结构成员,OSTCBId:存储任务的识别码。OSTCBNext和OSTCBPrev:任务控制块OS_TCBs双向链接,将任务控制块链接起来。该链表在时钟节拍函数OSTimeTick()中使用,用于刷新各个任务的任务延迟变量OSTCBDly,每个任务的任务控制块OS_TCB在任务建立的时候被链接到链表中,在任务删除的时候从链表中被删除。双向连接的链表使得任一成员

17、都能被快速插入或删除,任务控制块结构成员,OSTCBEventPtr:指向事件控制块的指针。OSTCBMsg:指向传给任务的消息的指针。OSTCBDly:任务延时的时钟节拍数。当需要把任务延时若干时钟节拍时,或者需要把任务挂起一段时间以等待某事件的发生时需要用到这个变量。如果这个变量为0,表示任务不延时,或者表示等待事件发生的时间没有限制.,任务控制块结构成员,OSTCBStat:任务状态字,可取下列值:OS_STAT_RDY:处于就绪状态OS_STAT_SEM:处于等待信号量状态OS_STAT_MBOX:处于等待邮箱状态OS_STAT_Q:处于等待消息队列状态OS_STAT_SUSPEND:

18、处于被挂起状态OS_STAT_MUTEX:处于等待互斥信号量状态,任务控制块结构成员,OSTCBPrio:任务优先级。高优先级任务的OSTCBPrio值小,低优先级任务的 OSTCBPrio值大OSTCBX、OSTCBY、OSTCBBitX与OSTCBBitY:与优先级有关的量,用于加速任务进入就绪态的过程或进入等待事件发生状态的过程。这些值是在任务建立时算好的,或者是在改变任务优先级时算出的。,任务控制块结构成员,任务控制块结构成员,OSTCBDelReq:一个布尔量,用于表示该任务是否需要删除。,2)任务控制块链表,任务控制块空闲链表:用于管理空闲任务的控制块的链表。系统初始化时,初始化函

19、数OSInit()将创建一个任务控制块空闲缓冲池,其中有一定数量的空任务控制块,并将其链接成一个单向链表,即空闲链表,并用OSTCBFreeList 指向表头。当建立一个任务时,即将空闲链表表头指针OSTCBFreeList指向的空任务控制块赋给该任务,然后将OSTCBFreeList指向链表中的下一个空任务控制块,2)任务控制块链表,任务控制块空闲链表(List of free OS_TCBs),2)任务控制块链表,任务控制块使用链表(双向),使用链表用于管理已建立任务的控制块,3)任务控制块初始化,任务控制块初始化函数OSTCBInit()做三件事:1、从空任务控制块链表中获取一个任务控制

20、块;2、用任务的属性值对任务控制块各个成员进行赋值;3、把这个任务控制块链入到任务控制块使用链表的头部。,3)任务控制块初始化-OSTCBInit(),/从空闲的OS_TCB缓冲池中获得一个OS_TCB,/如果OS_TCB池中有空闲的OS_TCB,它就被初始化了,/一旦OS_TCB被分配,该任务的创建者就已经完全拥有它了,不担心被同时建立的另一个任务夺取,故可以重新开中断,并继续初始化OS_TCB的数据单元。,3)任务控制块初始化-OSTCBInit(),3)任务控制块初始化-OSTCBInit(),3)任务控制块初始化-OSTCBInit(),3)任务控制块初始化-OSTCBInit(),/

21、将OS_TCB插入到已建立任务的OS_TCB的双向链表中,该双向链表开始于OSTCBList,而一个新任务的OS_TCB常常被插入到链表的表头,3)任务控制块初始化-OSTCBInit(),OSTCBList=ptcb,/使任务进入就绪态,/返回一个代码表明OS_TCB已经被分配和初始化了,3)任务控制块初始化-OSTCBInit(),第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,4 任务就绪表,1)任务就绪表结构2)任务就绪表操作

22、使任务进入就绪态使任务脱离就绪态找出进入就绪态的优先级最高的任务,1)任务就绪表结构,就绪表是保存任务就绪标志的表,表中的每一位对应一个任务,某任务处于就绪态时,表中相应位置1.就绪表有两个变量:OSRdyGrp和OSRdyTbl,OSRdyGrp,2)任务就绪态表操作,OSRdyGrp|=OSMapTblprio 3;OSRdyTblprio3|=OSMapTblprio,使 任务进入就绪态,2)任务就绪态表操作,例 1 使优先级为12的任务进入就绪状态,12=1100b,OSRdyGrp|=OSMapTblprio 3|=OSMapTbl1b|=00000010OSRdyTblprio 3

23、|=OSMapTblprio&0 x07|=OSMapTbl100b|=OSMapTbl4|=00010000即OSRdyGrp的第1位置1,OSRdyTbl1的第4位置1,2)任务就绪态表操作,例2 使优先级为21的任务进入就绪态,21=10 101b,OSRdyGrp|=OSMapTblprio 3|=OSMapTbl10b=OSMapTbl2|=00000100OSRdyTblprio 3|=OSMapTblprio&0 x07|=OSMapTbl101b|=OSMapTbl5|=00100000即OSRdyGrp的第2位置1,OSRdyTbl2的第5位置1,2)任务就绪态表操作,使任务

24、脱离就绪态将就绪任务表数组OSRdyTblprio3中相应元素的相应位清零,且当OSRdyTblprio3中的所有位都为零时,即全组任务中没有一个进入就绪态时,OSRdyGrp的相应位才为零。例 使优先级为12的任务脱离就绪表 If(OSRdyTbl1,If(OSRdyTblprio3,OSRdyTblprio3|=OSMapTblprio&0 x07,OSRdyGrp|=OSMapTblprio 3,2)任务就绪态表操作,y=1,x=4,prio=12,y=2,x=4,prio=20,例,INT8U const OSUnMapTbl=0,0,1,0,2,0,1,0,3,0,1,0,2,0,1

25、,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

26、 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

27、,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;,优先级判定表,2)任务就绪态表操作,例1 已知OSRdyGrp=01101000b,OSRdyTbl3=11100100b,找出进入就绪态的优先级最高的任务OSRdyGrp=01101000b=0 x68,查OSUnMapTbl0 x68得到的值是3,y=3。OSRdyTbl3=11100100b=0 xE4,则OSUn

28、MapTbl0 xE4的值是2,x=2。Prio=(y 3)+x=3*8+2=26。查任务控制块优先级表数组OSTCBPrioTbl26,即可得到指向该任务的任务控制块OS_TCB的指针.,2)任务就绪态表操作,例2 已知OSRdyGrp=00100100b,OSRdyTbl2=00010010b,找出进入就绪态的优先级最高的任务y=OSUnMapTblOSRdyGrp=OSUnMapTbl100100b=OSUnMapTbl0 x24=2x=OSUnMapTblOSRdyTbly=OSUnMapTblOSRdyTbl2=OSUnMapTbl00010010b=OSUnMapTbl0 x12=

29、1prio=(y 3)+x=(23)+1=17,第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,5 任务调度,任务调度器任务切换给调度器上锁和开锁,1)任务调度器,任务调度(Task Scheduling)C/OS-总是运行进入就绪态任务中优先级最高的任务;调度器的工作是确定哪个任务优先级最高以及下面该哪个任务运行了;任务级的调度由函数OSSched()完成,中断级的调度由另一个函数OSIntExt()完成的。,1)任务调度器(the

30、 Task Scheduler),2)任务切换,任务级的任务切换需完成以下2步操作:将被挂起任务的处理器寄存器推入堆栈将较高优先级任务的寄存器值从堆栈中恢复到寄存器中任务级的任务切换由OS_TASK_SW()宏完成.#define OS_TASK_SW()OSCtxSw(),任务切换OS_TASK_SW()的代码,Void OSCtxSw(void)将R1,R2,R3及R4推入当前堆栈;OSTCBCur-OSTCBStkPtr=SP;/SP入控制块 OSTCBCur=OSTCBHighRdy;SP=OSTCBHighRdy-OSTCBSTKPtr;将R4,R3,R2及R1从新堆栈中弹出;,保存

31、当前,恢复即将,注:设处理器只有4个寄存器,调用OS_TASK_SW()前的数据结构,保存当前CPU寄存器的值,(3),重新装入要运行的任务,低优先级任务 OS_TCB,存贮器低地址,存贮器高地址,堆栈方向,重新装入要运行的任务,低优先级任务 OS_TCB,存贮器低地址,存贮器高地址,堆栈方向,SP,R1,R2,R3,R4,PC,PSW,存贮器低地址,存贮器高地址,高优先级任务 OS_TCB,OSTCBCur(1),(2),CPU,(4),OSTCBHighRdy,OSCtxSw,OSCtxSw,OSCtxSw,3)给调度器上锁与开锁,上锁OSSchedlock()与开锁OSSchedUnlo

32、ck()函数用于禁止与允许任务调度。调用上锁函数的任务可一直保持对CPU的控制权(无论是否有优先级更高的任务进入了就绪态),直到调用开锁函数后,任务调度才得到允许。上锁和开锁函数必须成对使用上锁函数不影响中断响应。OSLockNesting跟踪OSSchedLock()函数被调用的次数,C/OS-允许嵌套深度达255层。当OSLockNesting等于零时,调度重新得到允许,OSSchedUnlock()调用OSSched。,3)给调度器上锁与开锁,调用OSSchedLock()以后,用户的应用程序不得使用任何能将现行任务挂起的系统调用。即用户程序不得调用OSMboxPend()、OSQPen

33、d()、OSSemPend()、OSTaskSuspend(OS_PR1O_SELF)、OSTimeDly()或OSTimeDlyHMSM(),直到OSLockNesting回零为止。因为调度器上了锁,用户就锁住了系统,任何其它任务都不能运。,OSSchedLock(),OSSchedUnlock(),第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,6 任务的创建,OSTaskCreate()-建立任务函数(调用OSTaskStkIn

34、it()与 OSTCBInit()OSTaskCreateExt()-建立任务扩展函数创建任务的一般方法,1)OSTaskCreate(),/检测分配给任务的优先级是否有效,Task:指向任务代码的指针Pdata:传递给任务的参数的指针Ptos:指向任务堆栈栈顶指针Prio:任务优先权,/确保在规定的优先级上还没有建立任务。,/如果拟分配的优先级是空闲的,则放置一个非空指针来保留该优先级,/建立任务堆栈,返回新堆栈栈顶(psp),并保存在任务的0S_TCB中,/从空闲的OS_TCB池中获得并初始化一个OS_TCB,在0S_CORE.C文件中,1)OSTaskCreate(),/如果函数是在某任

35、务的执行中被调用,应调用调度函数以判断新建立的任务是否比原来的任务有更高的优先级,若是,内核作任务切换,1)OSTaskCreate(),if(err=OS_NO_ERR)(7),/检验返回代码,如果成功,给OSTaskCtr加1,OSTaskCtr用于保存产生的任务数目,1)OSTaskCreate(),3)创建任务的一般方法,3)创建任务的一般方法,第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,7 挂起和恢复任务求,挂起任务,O

36、STaskSuspend(INT8U prio)挂起自已;参数prio=OS_PRIO_SELF;从就绪表中清除;OSTCBStat|=OS_STAT_SUSPEND调用调度函数OSSched()。挂起其它任务参数prio=待挂起任务的优先级从就绪表中清除OSTCBStat|=OS_STAT_SUSPEND,7 挂起和恢复任务求,被挂起的任务只能通过调用OSTaskResume()函数来恢复。若被挂起的任务同时也在等待(OSTCBDly0),在对任务做取消挂起操作时,只能将其恢复为非挂起态,不能将其置为就绪态,要继续等待延时期满时,才能转入就绪状态。,OSTaskSuspend(),/检验用户

37、是否通过指定 OS_PRIO_SELF来挂起调用本函数的任务本身,/用户也可以通过指定优先级来挂起调用本函数的任务,/检验要挂起的任务是否存在,OSTaskSuspend(),OSTaskSuspend(),/就绪表中被移除,/在任务的OS_TCB中设置OS_STAT_SUSPEND标志以表明任务正在被挂起,/OSTaskSuspend()只有在被挂起的任务是调用本函数的任务本身的情况下才调用任务调度程序。,7 挂起和恢复任务求,恢复任务,OSTaskResume()被挂起的任务只有通过调用OSTaskResume()才能恢复。,/要恢复的任务必须是存在的,因为需要操作它的任务控制块OS_TC

38、B(2),OSTaskResume().,OSTaskResume().,/该任务必须是被挂起的(3),/通过清除OSTCBStat域中的OS_STAT_SUSPEND位取消挂起(4),/要使任务处于就绪状态,OS_TCBDly域必须为0(5),OSTaskResume().,第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,8 其它任务管理函数,1)删除任务2)改变任务的优先级3)获取任务的信息,1)删除任务,删除任务,OSTaskD

39、el()删除任务,是将任务返回并处于休眠状态,并不是说任务的代码被删除了,只是任务的代码不再被C/OS-调用。调用OSTaskDel()删除任务。OSTaskDel()不能删除空闲任务,也不能在ISR中被调用;OSTaskDel()首先判断优先级是否有效;从使用链表中删除控制块;从就绪表或等待事件表中清除;将控制块放回空闲链表。,/要删除的任务不能是空闲任务,因为删除空闲任务是不允许,OSTaskDel(),/不能在ISR例程中删除一个任务,因为这也是不被允许的,/调用此函数的任务可以通过指定OS_PRIO_SELF参数来删除自已,OSTaskDel(),/将时钟延迟数清零,以确保自己重新允许

40、中断的时候,ISR不会使该任务就绪,/置任务标志以阻止其它任务或ISR让该任务重新开始执行。,/阻止任务调度程序在删除过程中切换到其它的任务中去;,OSTaskDel(),/重新允许中断以减少中断的响应时间。这样,就能处理中断服务了,但由于它增加了OSLockNesting,ISR执行完后会返回到被中断任务,从而继续任务的删除工作,/重新关中断后,它通过锁定嵌套计数器减一以重新允许任务调度,用户可以在这里删除或释放自定义的TCB附加数据域,/将指向被删除的任务的OS_TCB的指针指向NULL,就从优先级数组中将OS_TCB去除。再接着将被删除的任务的OS_TCB从OS_TCB双向链表中移除,/

41、被删除的任务位于表头,/被删除的任务位于表中间,OSTaskDel(),OS_TCB返回到空闲OS_TCB表中,允许其它任务的建立,最后调用任务调度程序来查看在OSTaskDel()重新允许中断的时候(11),中断服务子程序是否曾使更高优先级的任务处于就绪状态(18)。,OSTaskDel(),1)删除任务,请求删除任务,OSTaskDelReq()有时候,任务会占用一些内存缓冲区或信号量一类的资源,这时假如另一个任务试图删除该任务,这些被占用的资源就会因为没被释放而丢失,导致存储器漏洞,这是任何嵌入式系统都无法接受的。在这种情况下,用户可以想法子让拥有这些资源的任务在使用完资源后,先释放资源

42、,再删除自己。可以通过OSTaskDelReq()函数来完成该功能。,OSTaskDelReq().,2)改变任务的优先级,改变任务的优先级,OSTaskChangePrio()在用户建立任务的时候会分配给任务一个优先级。在程序运行期间,用户可以通过调用OSTaskChangePrio()来改变任务的优先级。换句话说,就是C/OS-允许用户动态的改变任务的优先级。OSTaskChangePrio()可以改变调用本函数的任务(当前任务)的优先级或其它任务的优先级.,/不能改变空闲任务的优先级,只能改变调用本函数的任务或者其它任务的优先级,OSTaskChangePrio(),/检验新优先级是否是

43、合法的,/如果新优先级是合法的,则保留这个优先级,OSTaskChangePrio(),/检验当前任务是否想改变它的优先级。然后检查想要改变优先级的任务是否存在(6)。,/插入NULL指针将指向当前任务OS_TCB的指针从优先级数组中移除(7),/检验想要改变优先级的任务是否就绪(8),/如果该任务处于就绪状态,必须在当前的优先级下从就绪表中移除(9),,/将任务插入就绪表,OSTaskChangePrio(),/如任务在等待某一事件的发生,必须将任务从事件控制块(在旧的优先级下)中移除。并在新的优先级下将事件插入到等待队列中(12),OSTaskChangePrio(),/将指向任务OS_T

44、CB的指针存到OSTCBPrioTbl中(13)。新的优先级被保存在OS_TCB中(14),重新计算的值也被保存在OS_TCB中(15)。OSTaskChangePrio()完成了关键性的步骤后,在新的优先级高于旧的优先级或新的优先级高于调用本函数的任务的优先级情况下,任务调度程序就会被调用(16)。,OSTaskChangePrio(),OSTaskChangePrio(),3)获取任务的信息,获得有关任务的信息,OSTaskQuery()应用程序可以通过调用OSTaskQuery()函数来获得自身或其它任务的信息。该函数获得的只是指定任务的任务控制块OS_TCB中内容的拷贝。要调用该函数,

45、应用程序必须为OS_TCB分配存储空间。这个OS_TCB的数据空间与C/OS-分配给任务控制块OS_TCB的数据空间完全不同。在调用了该函数后,这个OS_TCB包含了指定任务的OS_TCB的副本.不要改变OSTCBNext与OSTCBPrev的指向.本函数只用来了解任务正在干什么-本函数是一个有用的调试工具.,3)获取任务的信息,OSTaskQuery(),第2章 uC/OS-II中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,C/OS-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,9 C/OS-的初始化和任务的

46、启动,C/OS-初始化 OSIint()初始化函数负责初始化C/OS-所有的变量和数据结构(见OS_CORE.C)。OSInit()先后做以下事情:初始化全局变量初始化就绪表建空闲数据缓冲池(空任务控制块、空事件控制块、空消息队列控制块、空存储器管理控制块)建立空闲任务OSTaskIdle()(优先级为S_LOWEST_PRIO)建立统计任务OSTaskStat()(如果统计任务允许位和任务建立扩展允许位都设为1,优先级为OS_LOWEST_PRIO-1)。,初始化全局变量,0,初始化就绪表,0,0,0,空闲缓冲池,空任务控制块空闲缓冲池,空闲缓冲池,空事件、空消息队列与空存储器管理控制块空闲

47、缓冲池,建空闲任务与统计任务,void Main(void)/int argc,char*argvchar Id0=4;ARMTargetInit();/*needed by uC/OS*/OSInit();OSTimeSet(0);/*create the start task*/OSTaskCreate(TaskStart,(void*)0,void OSInit(void)INT16U i;OSTime=0L;/*Clear the 32-bit system clock*/OSIntNesting=0;/*Clear the interrupt nesting counter*/OSL

48、ockNesting=0;/*Clear the scheduling lock counter*/#if OS_TASK_CREATE_EN|OS_TASK_CREATE_EXT_EN|OS_TASK_DEL_EN OSTaskCtr=0;/*Clear the number of tasks*/#endif OSRunning=FALSE;/*Indicate that multitasking not started*/OSIdleCtr=0L;/*Clear the 32-bit idle counter*/#if OS_TASK_STAT_EN/*Statistic task is

49、not ready*/#endif,OSCtxSwCtr=0;/*Clear the context switch counter*/OSRdyGrp=0;/*Clear the ready list*/for(i=0;i OS_RDY_TBL_SIZE;i+)OSRdyTbli=0;OSPrioCur=0;OSPrioHighRdy=0;OSTCBHighRdy=(OS_TCB*)0;/*TCB Initialization*/OSTCBCur=(OS_TCB*)0;OSTCBList=(OS_TCB*)0;for(i=0;i(OS_LOWEST_PRIO+1);i+)OSTCBPrioTb

50、li=(OS_TCB*)0;for(i=0;i(OS_MAX_TASKS+OS_N_SYS_TASKS-1);i+)OSTCBTbli.OSTCBNext=,OSTCBTblOS_MAX_TASKS+OS_N_SYS_TASKS-1.OSTCBNext=(OS_TCB*)0;/*Last OS_TCB*/OSTCBFreeList=/*Initialize the message queue structures*/#endif,#if OS_MEM_EN#endif,#else#if OS_TASK_CREATE_EXT_EN OSTaskCreateExt(OSTaskIdle,(void

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号