第5章 嵌入式OS 任务管理与调度_第1页
第5章 嵌入式OS 任务管理与调度_第2页
第5章 嵌入式OS 任务管理与调度_第3页
第5章 嵌入式OS 任务管理与调度_第4页
第5章 嵌入式OS 任务管理与调度_第5页
已阅读5页,还剩161页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第五章

任务管理与调度

1主要内容概述任务任务管理任务调度优先级反转25.1概述TaskdemobasedonucOSintmain(void){//InitializeuCOS-II.OSInit();//CreatethefirsttaskOSTaskCreate(TestTask1,(void*)11,&TestTaskStk1[TASK_STK_SIZE],11);//Startmultitasking.OSStart();return0;}voidTestTask1(void*pdata){printf("%4u:*****TestTask1Firstcall*****\n",OSTime);

//Create3othertasksOSTaskCreate(TestTask2,(void*)22,&TestTaskStk2[TASK_STK_SIZE],22);OSTaskCreate(TestTask3,(void*)33,&TestTaskStk3[TASK_STK_SIZE],33);OSTaskCreate(TestTask4,(void*)10,&TestTaskStk3[TASK_STK_SIZE],10);while(1){

printf("%4u:*****TestTask11*****\n",OSTime);

OSTimeDly(1);}}3voidTestTask2(void*pdata){

while(1){printf("%4u:*****TestTask22*****\n",OSTime);

OSTimeDly(1);

}}voidTestTask3(void*pdata){

while(1){

printf("%4u:*****TestTask33*****\n",OSTime);OSTimeDly(1);}}voidTestTask4(void*pdata){

while(1){printf("%4u:+++++TestTask10+++++\n",OSTime);OSTaskSuspend(10);//Suspendyourself

}}

4采用多任务的好处任务的规模较小

每个任务更容易编码和调试,其质量也更容易得到保证

不少应用本身就是由多个任务构成的如一个应用可能需要进行以下任务的处理:计算、从网络获取数据和刷新显示屏幕采用多任务的处理方式是应用问题的一个非常自然的解决方式任务之间具有较高的独立性,耦合性小

通过增加新的任务就能方便的扩充系统功能实时性强保证紧急事件得到优先处理成为可能5在嵌入式实时系统中任务(task)通常为进程(process)和线程(thread)的统称任务是调度的基本单位进程最初由Multics的设计者在60年代提出来的,主要包括以下内容:一个正在执行的程序;计算机中正在运行的程序的一个实例;可以分配给处理器,并由处理器执行的一个实体;由一个顺序的执行线程、一个当前状态和一组相关的系统资源所刻画的活动单元。6进程由代码、数据、堆栈和进程控制块构成。进程控制块包含了操作系统用来控制进程所需要的信息:进程状态CPU寄存器调度信息内存管理信息I/O状态信息等早期的进程,包含了以下两个方面的内容:资源。进程是资源分配的基本单位,一个进程包括一个保存进程映像的虚拟地址空间、主存、I/O设备和文件等资源。调度执行。进程作为操作系统的调度实体,是调度的基本单位。7随着操作系统的发展,进程所包含的两个方面的内容逐渐被分开:轻量级进程或线程:调度执行的单位

进程:资源分配的单位

线程是进程内部一个相对独立的控制流,由线程上下文和需要执行的一段程序指令构成在进程中,所有线程共享该进程的状态和资源,可以访问相同的数据使用线程的优势:

创建:在一个已有进程中创建一个新线程比创建一个全新的进程所需的时间开销少;终止:终止一个线程比终止一个进程所花费的时间少;切换:线程切换比进程切换所花费的时间少;通信:使同一进程内部不同线程之间的通信效率得到显著提高。在大多数操作系统中,不同进程之间的通信需要内核的干预,而同一进程内部不同线程之间则可直接通信。8引入线程的概念后,可把进程和线程的使用分为以下几种模型:单进程/单线程模型(如MS-DOS):整个系统只有一个进程、一个线程单进程/多线程模型:在单进程/多线程模型中,整个系统有一个进程、多个线程多进程/单线程模型(如传统的UNIX):在多进程/单线程模型中,整个系统有多个进程,每个进程只有一个线程多进程/多线程模型(如WindowsNT、Solaris、Mach等):在多进程/多线程模型中,系统有多个进程,每个进程又可包含多个线程9图5.1进程和线程的使用模型10大多数嵌入式实时内核:单进程/多线程模型,或简单地称为任务模型

把整个应用当作一个没有定义的进程来对待;应用则被划分为多个任务的形式来进行处理。也有一些嵌入式实时操作系统采用了多进程/多线程模型:系统中包含多个进程,每个进程对应又包含多个线程多进程/多线程模型适合于处理复杂的应用任务模型则适用于实时性要求较高的、相对简单的应用11任务划分程序在CPU中是以任务的方式在运行,所以要将系统的处理框图转化为多任务流程图,对处理进行任务划分。任务划分存在这样一对矛盾:如果任务太多,必然增加系统任务切换的开销;如果任务太少,系统的并行度就降低了,实时性就比较差。在任务划分时要遵循以下原则:◆I/O原则:不同的外设执行不同任务。◆优先级原则:不同优先级处理不同的任务。◆大量运算:归为一个任务。◆功能耦合:归为一个任务。◆偶然耦合:归为一个任务。◆频率组合:对于周期时间,不同任务处理不同的频率。如果在具体分析一个系统时发生原则冲突,则要为每一个原则针对具体的系统设定“权重”,必要时可以通过计算“权重”来最终确定如何划分任务。125.2任务任务的定义及其主要特性任务的内容任务的分类任务参数135.2.1任务的定义及其主要特性

任务是一个具有独立功能的无限循环的程序段的一次运行活动,是实时内核调度的单位,具有以下特性:动态性:任务状态是不断变化的。

一般分为就绪态、运行态和等待态。在多任务系统中,任务的状态将随着系统的需要不断进行变化。并行性:系统中同时存在多个任务,这些任务在宏观上是同时运行的。异步独立性:

每个任务各自按相互独立的不可预知的速度运行,走走停停。

14任务的实现创建任务的系统服务OSTaskCreate()INT8UOSTaskCreate(

void(*task)(void*pd),//任务代码指针

void*pdata,//任务参数指针

OS_STK*ptos,//任务栈的栈顶指针

INT8Uprio//任务的优先级

);OSTaskCreateExt()提问:C/OS-II中的任务是进程还是线程?15任务主函数一个任务通常是一个无限循环(返回值类型void)voidMyTask(void*pdata){while(1){dosomething;waiting; dosomething; }}16任务也可以自我删除(并非真的删除,只是内核不再知道该任务)voidMyTask(void*pdata){....../*用户代码*/OSTaskDel(OS_PRIO_SELF);}175.2.2任务的内容

任务主要包含以下内容:代码:一段可执行的程序数据:程序所需要的相关数据(变量、工作空间、缓冲区等)堆栈

程序执行的上下文环境18任务的内容

/﹡ioTaskimplementsdataobtainingandhandlingcontinuously﹡/voidioTask(void){ intdata;

initial(); /﹡Thefollowingsentencesgetdataandhandledatacontinuously﹡/

while(TRUE)

{ data=getData(); handleData(data); }}任务所包含的程序通常为一个具有无限循环的程序

19voidYourTask(void*pdata){for(;;){/*USERCODE*/CalloneofuC/OS-II’sservices:OSFlagPend();OSMboxPend();OSMutexPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyHMSM();/*USERCODE*/}}voidYourTask(void*pdata){/*USERCODE*/OSTaskDel(OS_PRIO_SELF);}20voidTestTask2(void*pdata){

while(1){printf("%4u:*****TestTask22*****\n",OSTime);

OSTimeDly(1);}}voidTestTask3(void*pdata){

while(1){

printf("%4u:*****TestTask33*****\n",OSTime);OSTimeDly(1);}}voidTestTask4(void*pdata){

while(1){printf("%4u:+++++TestTask10+++++\n",OSTime);OSTaskSuspend(10);//Suspendyourself

}}21任务的内容

任务与程序的区别:任务能真实地描述工作内容的并发性,而程序不能;程序是任务的组成部分除程序外,任务还包括数据、堆栈及其上下文环境等内容;程序是静态的,任务是动态的;任务有生命周期,有诞生、有消亡,是短暂的;而程序是相对长久的;一个程序可对应多个任务,反之亦然;任务具有创建其他任务的功能,而程序没有。22任务的内容

任务上下文环境(context)包括了实时内核管理任务、以及处理器执行任务所需要的所有信息。任务优先级任务的状态等实时内核所需要的信息以及处理器的各种寄存器的内容(hardwarecontext):程序计数器、堆栈指针、通用寄存器等的内容

任务的上下文环境通过任务控制块(taskcontrolblock,TCB)来体现。

23多任务系统示意图

245.2.3任务的分类

按照到达情况的可预测性,任务可以划分为:周期任务(periodictask)非周期任务按照重要程度,可分为:关键任务(criticaltask)非关键任务(noncriticaltask)25任务的分类

周期任务与非周期任务

周期任务每隔一个固定的时间间隔就会执行一次。飞行器可能需要每隔100ms获得一次关于飞行器的速度、高度和姿态数据,控制传感器获取这些数据就需要通过周期任务来进行。非周期任务执行的间隔时间则为不确定的。移动通信设备中的通信任务,该任务只有在需要进行通信的情况下才会得到执行。非周期任务分为:sporadictask:有最小到达间隔时间限制aperiodictask:没有到达时间限制26任务的分类

关键任务与非关键任务

关键任务:为需要得到及时执行的任务,否则将出现灾难性的后果飞行器中用于处理生命支持系统和稳定性控制系统的任务非关键任务:

如果没有得到及时执行,则不会产生严重后果27任务参数

任务参数:优先级(priority)周期(period)计算时间(computationtime)就绪时间(readytime)截止时间(deadline)28任务参数

任务的优先级

表示任务对应工作内容在处理上的优先程度优先级越高,表明任务越需要得到优先处理飞行器中处理稳定性控制的任务,就需要具有较高的优先级,一旦执行条件得到满足,应及时得到执行任务的优先级分为静态优先级和动态优先级。静态优先级:任务的优先级被确定后,在系统运行过程中将不再发生变化;动态优先级:系统运行过程中,任务的优先级是可以动态变化的。

29任务参数

周期

周期任务所具有的参数,表示任务周期性执行的间隔时间任务的计算时间

任务在特定硬件环境下被完整执行所需要的时间,也被称为是任务的执行时间(executiontime)。由于任务每次执行的软件环境的差异性,导致任务在各次具体执行过程中的计算时间各有不同。通常用最坏情况下的执行时间(worstcasetime)或是需要的最长执行时间来表示,也可用统计时间(statisticaltime)来表示。30任务参数

任务的就绪时间

任务具备了在处理器上被执行所需要条件时的时间任务的截止时间意味着任务需要在该时间到来之前被执行完成。截止时间可以通过绝对截止时间(absolutedeadline)和相对截止时间(relativetime)两种方式来表示相对截止时间为任务的绝对截止时间减去任务的就绪时间。截止时间可以分为强截止时间(harddeadline)和弱截止时间(softdeadline)两种情况:具有强截止时间的任务即为关键任务,如果截止时间不能得到满足,就会出现严重的后果。拥有关键任务的实时系统又被称为强实时(hardreal-time)系统,否则称为弱实时(softreal-time)31μC/OS-Ⅱ可以管理多达64个任务;每个任务被赋以不同的优先级,取值从0到OS_LOWEST_PRIO-2,数值越小,优先级越高;系统保留了优先级为0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1以及OS_LOWEST_PRI0这8个任务以被将来使用,用户可以有56个应用任务;任务的优先级同样也是它的标识号ID。OS_CFG.H

中定义=63325.3任务管理

任务状态与变迁空闲任务任务控制块任务切换任务队列任务管理机制335.3.1任务状态与变迁

任务拥有的资源情况是不断变化的,导致任务状态也表现出不断变化的特性。不同的实时内核实现方式对任务状态的定义不尽相同,但是都可以概括为三种基本的状态:等待(waiting):任务在等待某个事件的发生;就绪(ready):任务等待获得处理器资源;执行(running):任务获得处理器资源,所包含的代码内容正在被执行。34任务状态与变迁

在单处理器系统中:任何时候都只有一个任务在CPU中执行

如果没有任何事情可做,就运行空闲任务执行空操作任何一个可以执行的任务都必须处于就绪状态

调度程序从任务的就绪队列中选择下一个需要执行的任务。处于就绪状态的任务拥有除CPU以外的其他所有需要的资源。任务还可能处于等待状态如任务在需要等待I/O设备或其他任务提供的数据,而数据又还没有到达该任务的情况下,就处于等待状态35任务状态与变迁

任务会在不同的状态之间进行转换,即任务状态的变迁对于处于就绪状态的任务,获得CPU后,就处于执行状态。处于执行状态的任务如果被高优先级任务所抢占,任务又会回到就绪状态。处于执行状态的任务如果需要等待资源,任务会被切换到等待状态。对处于等待状态的任务,如果需要的资源得到满足,就会转换为就绪状态,等待被调度执行。36任务状态变迁37三个任务进行状态转换的过程

包含三个任务和一个调度程序。调度程序用来确定下一个需要投入运行的任务,因此调度程序本身也需要占用一定的处理时间。38删除任务TaskstatesandtransitionofuCOS

39空闲任务(Idletask)

内核总是创建一个空闲任务OSTaskIdle();总是设置为最低优先级,OS_LOWEST_PRIOR;当所有其他任务都未在执行时,空闲任务开始执行;应用程序不能删除该任务;空闲任务的工作就是把32位计数器OSIdleCtr加1,该计数器被统计任务所使用;40voidOS_TaskIdle(void*pdata){/*Preventcompilerwarningfornotusing'pdata‘*/pdata=pdata;for(;;){OS_ENTER_CRITICAL();OSIdleCtr++;OS_EXIT_CRITICAL();/*CalluserdefinableHOOK*/OSTaskIdleHook();}}OSIdleCtrisusedbythestatisticstasktodeterminehowmuchCPUtime(inpercentage)isactuallybeingconsumedbytheapplicationsoftware.

IdleTaskofuCOS415.3.2任务控制块

任务管理是通过对任务控制块(taskcontrolblock,TCB)的操作来实现的。任务控制块是包含任务相关信息的数据结构包含了任务执行过程中所需要的所有信息。任务控制块大都包括以下信息:任务的名字任务执行的起始地址任务的优先级任务的状态任务的硬件上下文(堆栈指针、PC和寄存器等)

任务的队列指针等内容42图5.7任务控制块示意图

TasknameTaskIDTaskstatusTaskpriorityTaskcontext(registersandflagsofCPU)…43任务控制块

为节约内存,任务数量通常需要进行预先配置按照配置的任务数量初始化任务控制块,一个任务对应一个初始的任务控制块,形成一个空闲任务控制块链。在任务创建时,实时内核从空闲任务控制块链中为任务分配一个任务控制块。随后对任务的操作,都是基于对应的任务控制块来进行的。当任务被删除后,对应的任务控制块又会被实时内核回收到空闲任务控制块链。44TCBofucOS

typedefstructos_tcb{OS_STK*OSTCBStkPtr;/*Pointertocurrenttopofstack*/#ifOS_TASK_CREATE_EXT_EN>0void*OSTCBExtPtr;/*PointertouserdefinabledataforTCBextension*/OS_STK*OSTCBStkBottom;/*Pointertobottomofstack*/INT32UOSTCBStkSize; /*Sizeoftaskstack(innumberofstackelements)*/INT16UOSTCBOpt; /*TaskoptionsaspassedbyOSTaskCreateExt()*/INT16UOSTCBId; /*TaskID(0..65535)*/#endifstructos_tcb*OSTCBNext; /*PointertonextTCBintheTCBlist*/structos_tcb*OSTCBPrev; /*PointertopreviousTCBintheTCBlist*/

45TCBofucOS

#if((OS_Q_EN>0)&&(OS_MAX_QS>0))||(OS_MBOX_EN>0)||(OS_SEM_EN>0)||(OS_MUTEX_EN>0)OS_EVENT*OSTCBEventPtr; /*Pointertoeventcontrolblock*/#endif#if((OS_Q_EN>0)&&(OS_MAX_QS>0))||(OS_MBOX_EN>0)void*OSTCBMsg; /*MessagereceivedfromOSMboxPost()orOSQPost()*/#endif46#if(OS_VERSION>=251)&&(OS_FLAG_EN>0)&&(OS_MAX_FLAGS>0)#ifOS_TASK_DEL_EN>0OS_FLAG_NODE*OSTCBFlagNode;/*Pointertoeventflagnode*/#endifOS_FLAGSOSTCBFlagsRdy;/*Eventflagsthatmadetaskreadytorun*/#endifINT16UOSTCBDly;/*Nbrtickstodelaytaskor,timeoutwaitingforevent*/INT8UOSTCBStat;/*Taskstatus*/INT8UOSTCBPrio;/*Taskpriority(0==highest,63==lowest)*/47OSTCBX;/*Bitpositioningroupcorrespondingtotaskpriority(0..7)*/INT8UOSTCBY;/*Indexintoreadytablecorrespondingtotaskpriority*/INT8UOSTCBBitX;/*Bitmasktoaccessbitpositioninreadytable*/INT8UOSTCBBitY;/*Bitmasktoaccessbitpositioninreadygroup*/#ifOS_TASK_DEL_EN>0BOOLEANOSTCBDelReq;/*Indicateswhetherataskneedstodeleteitself*/#endif}OS_TCB;485.3.3任务切换

任务切换当多任务内核决定运行另外的任务时,它把正在运行任务的当前状态(即CPU寄存器中的全部内容)保存到任务自己的栈区之中。然后把下一个将要运行的任务的当前状态从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行。这个过程就称为任务切换。任务切换时间任务切换所需要的时间取决于CPU有多少寄存器要入栈。CPU的寄存器越多,额外负荷就越重。495.3.3任务切换

任务切换(contextswitching)保存当前任务的上下文,并恢复需要执行的任务的上下文的过程。当发生任务切换时:当前正在运行的任务的上下文就需要通过该任务的任务控制块保存起来;把需要投入运行的任务的上下文从对应的任务控制块中恢复出来。50在时刻8即发生了任务切换,任务1的上下文需要保存到任务1的任务控制块中去。经过调度程序的处理,在时刻10任务2投入运行,需要把任务2的任务控制块中关于上下文的内容恢复到CPU的寄存器。51任务1执行一段时间后,由于某种原因,需要进行任务切换,进入实时内核的调度程序。调度程序首先把当前的上下文内容保存到任务1的任务控制块TCB1中,然后又把任务2的上下文从TCB2中恢复到CPU寄存器,随后任务2得到执行。任务2执行一段时间后,由于某种原因,需要进行任务切换,进入实时内核的调度程序。调度程序首先把当前的上下文内容保存到任务2的任务控制块TCB2中,然后又把任务1的上下文从TCB1中恢复到CPU寄存器,随后任务1得到执行。

52任务切换

任务切换将导致任务状态发生变化:当前正在运行的任务将由运行状态变为就绪或是等待状态;需要投入运行的任务则由就绪状态变为运行状态。53任务切换

任务切换具有如下基本步骤:

保存任务上下文环境;更新当前处于运行状态的任务的任务控制块的内容,如把任务的状态由运行状态改变为就绪或是等待状态;把任务的任务控制块移到相应的队列(就绪队列或是等待队列);选择另一个任务进行执行:调度;改变需要投入运行的任务的任务控制块的内容,把任务的状态变为运行状态;根据任务控制块,恢复需要投入运行的任务的上下文环境。54任务切换

任务切换的时机:

中断、自陷如当I/O中断发生的时候如果I/O活动是一个或多个任务正在等待的事件,内核将把相应的处于等待状态的任务转换为就绪状态同时,内核还将确定是否继续执行当前处于运行状态的任务,或是用高优先级的就绪任务抢占该任务

自陷由于执行任务中当前指令所引起,将导致实时内核处理相应的错误或异常事件,并根据事件类型,确定是否进行任务的切换55任务切换

运行任务因缺乏资源而被阻塞如,任务执行过程中进行I/O操作时(如打开文件),如果此前该文件已被其他任务打开,将导致当前任务处于等待状态,而不能继续执行时间片轮转调度时内核将在时钟中断处理程序中确定当前正在运行的任务的执行时间是否已经超过了设定的时间片;如果超过了时间片,实时内核将停止当前任务的运行,把当前任务的状态变为就绪状态,并把另一个任务投入运行56任务切换

高优先级任务处于就绪时如果采用基于优先级的抢占式调度算法,将导致当前任务停止运行,使更高优先级的任务处于运行状态57voidOS_Sched(void){INT8Uy;OS_ENTER_CRITICAL();if((OSIntNesting==0)&&(OSLockNesting==0)){/*Sched.onlyifallISRsdone¬locked*/y=OSUnMapTbl[OSRdyGrp];/*GetpointertoHPTready*/OSPrioHighRdy=(INT8U)((y<<3)+OSUnMapTbl[OSRdyTbl[y]]);if(OSPrioHighRdy!=OSPrioCur){/*NoCtxSwifcurrenttaskishighestrdy*/OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;/*Incrementcontextswitchcounter*/OS_TASK_SW();/*Performacontextswitch*/}}OS_EXIT_CRITICAL();

TaskschedulingofucOS58voidOSCtxSw(void){PUSHR1,R2,R3andR4ontothecurrentstack;OSTCBCur->OSTCBStkPtr=SP;OSTCBCur=OSTCBHighRdy;SP=OSTCBHighRdy->OSTCBStkPtr;POPR4,R3,R2andR1fromthenewstack;Executeareturnfrominterruptinstruction;

}OS_TASK_SW()59调用OS_TASK_SW()前的数据结构低优先级任务OS_TCBOSTCBCur(1)存贮器低地址存贮器高地址堆栈方向SPR1R2R3R4PCPSW存贮器低地址存贮器高地址高优先级任务OS_TCBOSTCBHighRdy(3)(2)CPU(4)(5)Context-switchinucOS

60保存当前CPU寄存器的值低优先级任务OS_TCBOSTCBCurPSWPCR1R2R3R4存贮器低地址存贮器高地址堆栈方向SPR1R2R3R4PCPSW存贮器低地址存贮器高地址高优先级任务OS_TCBOSTCBHighRdy(3)(2)CPU(4)(5)(1)(3)61重新装入要运行的任务低优先级任务OS_TCBOSTCBCurPSWPCR1R2R3R4存贮器低地址存贮器高地址堆栈方向SPR1R2R3R4PCPSWPSWPCR1R2R3R4存贮器低地址存贮器高地址高优先级任务OS_TCBOSTCBHighRdyOSTCBCur(1)(2)CPU(4)(4)(1)(3)(3)(4)62任务上下文切换时间

任务上下文切换时间:保存:保存当前运行任务上下文的时间;调度:选择下一个任务的调度时间;

恢复:将要运行任务的上下文的恢复时间。保存和恢复上下文的时间:取决于任务上下文的定义和处理器的速度。不同种类的处理器,任务上下文的定义不同,其内容有多有少。任务上下文切换的时间与调度(即选择下一个运行任务)的过程有关。强实时内核要求调度过程所花费的时间是确定的,即不能随系统中就绪任务的数目而变化。

与具体实现调度算法时所采用的数据结构有关。

635.3.4任务队列

任务队列通过任务控制块实现对系统中所有任务的管理。

单就绪队列和单等待队列

64任务队列

队列由任务控制块构成

65任务队列

单等待队列资源对应的事件发生时,实时内核需要扫描整个等待队列,搜索等待该资源的任务,并按照一定的策略选取任务,把任务的任务控制块放置到就绪队列。如果系统的资源和任务比较多,搜索等待该资源的任务所需要的时间就比较长,会影响整个系统的实时性。可采用一种多等待队列的处理方式资源对应的事件发生时,能够在较短的时间内确立等待该资源的任务等待队列。66任务队列

单就绪队列和多等待队列

67任务队列

对于就绪任务,如果采用上述队列方式进行管理,在基于优先级的调度处理中,要获得当前具有最高优先级的就绪任务:方式一:任务就绪时,把就绪任务的任务控制块放在就绪队列的末尾。调度程序需要从就绪队列的头部到尾部进行一次遍历,才能获得就绪队列中具有最高优先级的任务;方式二:就绪队列按照优先级从高到低的顺序排列。新的就绪任务到达时,需要插入到就绪队列的合适位置,确保就绪队列保持优先级从高到低排列的顺序性。68任务队列

在这两种处理方式中,所花费的时间与任务数量有密切的关系,具有不确定性。为提高实时内核的确定性,可采用一种被称为优先级位图的就绪任务处理算法。69FreeTCBsafterOS_TCBInit()inucOS

705.3.5任务管理机制

任务管理用来实现对任务状态的直接控制和访问。内核的任务管理是通过系统调用来体现,主要包括任务创建、任务删除、任务挂起、任务唤醒、设置任务属性等内容。创建任务删除任务挂起任务唤醒任务设置任务属性改变任务优先级获取任务信息

…….任务管理功能

71任务管理机制

创建任务的过程即为分配任务控制块的过程。在创建任务时,通常需要确定任务的名字和任务的优先级等内容,确立任务所能使用的堆栈区域。任务创建成功后,通常会为用户返回一个标识该任务的ID,以实现对任务的引用管理。删除任务把任务从系统中去掉,释放对应的任务控制块。挂起/唤醒任务把任务变为等待状态,可通过唤醒任务操作把任务转换为就绪状态。72任务管理机制

设置任务属性可以用来设置任务的抢占、时间片等特性,以确定是否允许任务在执行过程中被抢占或是对同优先级任务采用时间片轮转方式运行等。改变任务优先级用来根据需要改变任务的当前优先级。获取任务信息获得任务的当前优先级、任务的属性、任务的名字、任务的上下文、任务的状态等内容,便于用户进行决策。731.创建任务

任务创建为任务分配和初始化相关的数据结构。任务创建时通常需要使用如下信息:任务的名字任务的初始优先级任务栈任务属性任务对应的函数入口地址任务对应函数的参数任务删除时的回调函数

74创建任务

栈空间:由于不同任务运行时需要的大小不同,由内核进行任务栈的分配就不能适应应用任务的多样性需求。通常由用户指定任务运行过程中需要使用的栈空间。确定任务到底需要多少栈空间是一个比较困难的事情。大都需要进行一个反复修正的过程:在最开始的时候,根据应用的类型,为任务分配一个比预期估计更大的栈空间;使用栈检测函数,定期监控任务对栈的使用情况,并据此对任务栈的大小进行调整。75创建任务

任务可以包含多种属性任务是否可被抢占是否采用时间片轮转调度方式调度是否响应异步信号任务中开放的中断级别是否使用数字协处理器等内容如果任务需要进行浮点运算,在创建任务时实时内核应为任务分配浮点堆栈空间,以在任务切换时保存或是恢复数字协处理器的上下文内容。任务对应函数的入口地址

表示所创建任务起始执行的入口76创建任务

任务创建通常需要完成以下工作:获得任务控制块TCB根据实时内核用户提供的信息初始化TCB为任务分配一个可以唯一标识任务的ID使任务处于就绪状态,把任务放置到就绪队列进行任务调度处理77OSTaskCreateinucOSINT8UOSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT8Uprio){OS_STK*psp;INT8Uerr;OS_ENTER_CRITICAL();if(OSTCBPrioTbl[prio]==(OS_TCB*)0){/*Makesuretaskdoesn'talreadyexistatthispriority*/OSTCBPrioTbl[prio]=(OS_TCB*)1;/*Reservetheprioritytopreventothersfromdoingthesamethinguntiltaskiscreated.*/OS_EXIT_CRITICAL();psp=(OS_STK*)OSTaskStkInit(task,pdata,ptos,0);/*Initializethetask'sstack*/err=OS_TCBInit(prio,psp,(OS_STK*)0,0,0,(void*)0,0);if(err==OS_NO_ERR){OS_ENTER_CRITICAL();OSTaskCtr++;/*Incrementthe#taskscounter*/OS_EXIT_CRITICAL();if(OSRunning==TRUE){/*Findhighestprioritytaskifmultitaskinghasstarted*/OS_Sched();}}else{OS_ENTER_CRITICAL();OSTCBPrioTbl[prio]=(OS_TCB*)0;/*Makethispriorityavailabletoothers*/OS_EXIT_CRITICAL();}return(err);}OS_EXIT_CRITICAL();return(OS_PRIO_EXIST);}

78TaskdemobasedonucOS

intmain(void){//InitializeuCOS-II.OSInit();//CreatethefirsttaskOSTaskCreate(TestTask1,(void*)11,&TestTaskStk1[TASK_STK_SIZE],11);//Startmultitasking.OSStart();return0;}voidTestTask1(void*pdata){printf("%4u:*****TestTask1Firstcall*****\n",OSTime);

//Create3othertasksOSTaskCreate(TestTask2,(void*)22,&TestTaskStk2[TASK_STK_SIZE],22);OSTaskCreate(TestTask3,(void*)33,&TestTaskStk3[TASK_STK_SIZE],33);OSTaskCreate(TestTask4,(void*)10,&TestTaskStk3[TASK_STK_SIZE],10);while(1){

printf("%4u:*****TestTask11*****\n",OSTime);

OSTimeDly(1);}}79voidTestTask2(void*pdata){while(1){printf("%4u:*****TestTask22*****\n",OSTime);OSTimeDly(1);}}voidTestTask3(void*pdata){while(1){

printf("%4u:*****TestTask33*****\n",OSTime);OSTimeDly(1);}}voidTestTask4(void*pdata){while(1){printf("%4u:+++++TestTask10+++++\n",OSTime);OSTaskSuspend(10);//Suspendyourself

}}802.删除任务

内核根据任务创建时获得的ID删除指定的任务。在删除一个任务时,需要释放该任务所拥有的资源。释放任务所拥有的资源通常由内核和任务共同完成。内核通常只释放那些由内核为任务分配的资源如任务名字和TCB等内容所占用的空间。由任务自己分配的资源则通常由任务自身进行释放如任务的堆栈空间,以及其他一些任务申请的资源,信号量、timer、文件系统资源、I/O设备和使用malloc等函数动态获得的内存空间等。81删除任务

任务删除通常需要进行以下工作:根据指定的ID,获得对应任务的TCB把任务的TCB从队列中取出来,挂入空闲TCB队列释放任务所占用的资源82OSTaskDelinucOS

INT8UOSTaskDel(INT8Uprio){OS_EVENT*pevent;OS_TCB*ptcb;BOOLEANself;if(OSIntNesting>0){/*SeeiftryingtodeletefromISR*/return(OS_TASK_DEL_ISR);}OS_ENTER_CRITICAL();if(prio==OS_PRIO_SELF){/*Seeifrequestingtodeleteself*/prio=OSTCBCur->OSTCBPrio;/*Setprioritytodeletetocurrent*/}ptcb=OSTCBPrioTbl[prio];if(ptcb!=(OS_TCB*)0){/*Tasktodeletemustexist*/if((OSRdyTbl[ptcb->OSTCBY]&=~ptcb->OSTCBBitX)==0x00){/*Maketasknotready*/OSRdyGrp&=~ptcb->OSTCBBitY;}pevent=ptcb->OSTCBEventPtr;if(pevent!=(OS_EVENT*)0){/*Iftaskiswaitingonevent*/if((pevent->OSEventTbl[ptcb->OSTCBY]&=~ptcb->OSTCBBitX)==0){/*...removetaskfromeventctrlblock*/pevent->OSEventGrp&=~ptcb->OSTCBBitY;}}ptcb->OSTCBDly=0;/*PreventOSTimeTick()fromupdating*/ptcb->OSTCBStat=OS_STAT_RDY;/*Preventtaskfrombeingresumed*/if(OSLockNesting<255){OSLockNesting++;}OS_EXIT_CRITICAL();

83OS_Dummy();/*...DummyensuresthatINTswillbe*/OS_ENTER_CRITICAL();/*...disabledHERE!*/if(OSLockNesting>0){OSLockNesting--;}OSTaskDelHook(ptcb);/*Calluserdefinedhook*/OSTaskCtr--;/*Onelesstaskbeingmanaged*/OSTCBPrioTbl[prio]=(OS_TCB*)0;/*Clearoldpriorityentry*/if(ptcb->OSTCBPrev==(OS_TCB*)0){/*RemovefromTCBchain*/ptcb->OSTCBNext->OSTCBPrev=(OS_TCB*)0;OSTCBList=ptcb->OSTCBNext;}else{ptcb->OSTCBPrev->OSTCBNext=ptcb->OSTCBNext;ptcb->OSTCBNext->OSTCBPrev=ptcb->OSTCBPrev;}ptcb->OSTCBNext=OSTCBFreeList;/*ReturnTCBtofreeTCBlist*/OSTCBFreeList=ptcb;OS_EXIT_CRITICAL();OS_Sched();/*Findnewhighestprioritytask*/return(OS_NO_ERR);}OS_EXIT_CRITICAL();return(OS_TASK_DEL_ERR);}843.挂起任务

挂起指定任务,直到通过唤醒任务对任务进行解挂。一个任务可以把自己挂起当任务把自己挂起后,会引起任务的调度,实时内核将选取另外一个合适的任务进行执行。任务被挂起后,该任务将处于等待状态挂起任务通常需要进行以下工作:根据指定的ID,获得对应任务的TCB把任务的状态变为等待状态,并把TCB放置到等待队列如果任务自己挂起自己,进行任务调度85OSTaskSuspendinucOS

INT8UOSTaskSuspend(INT8Uprio){BOOLEANself;OS_TCB*ptcb;OS_ENTER_CRITICAL();if(prio==OS_PRIO_SELF){/*SeeifsuspendSELF*/prio=OSTCBCur->OSTCBPrio;self=TRUE;}elseif(prio==OSTCBCur->OSTCBPrio){/*Seeifsuspendingself*/self=TRUE;}else{self=FALSE;/*Nosuspendinganothertask*/}ptcb=OSTCBPrioTbl[prio];if(ptcb==(OS_TCB*)0){/*Tasktosuspendmustexist*/OS_EXIT_CRITICAL();return(OS_TASK_SUSPEND_PRIO);}if((OSRdyTbl[ptcb->OSTCBY]&=~ptcb->OSTCBBitX)==0x00){/*Maketasknotready*/OSRdyGrp&=~ptcb->OSTCBBitY;}ptcb->OSTCBStat|=OS_STAT_SUSPEND;/*Statusoftaskis'SUSPENDED'*/OS_EXIT_CRITICAL();if(self==TRUE){/*ContextswitchonlyifSELF*/OS_Sched();}return(OS_NO_ERR);}864.唤醒任务

根据任务ID解挂指定的任务。如果任务还在等待其他资源,任务解挂后仍然处于等待状态;否则,解挂后的任务将处于就绪状态。解挂任务通常需要进行以下工作:根据指定的ID,获得对应任务的TCB如果任务在等待其他资源,任务将仍然处于等待状态;否则,把任务的状态变为就绪状态,并把TCB放置到就绪队列进行任务调度87OSTaskResumeinucOS

INT8UOSTaskResume(INT8Uprio){OS_TCB*ptcb;OS_ENTER_CRITICAL();ptcb=OSTCBPrioTbl[prio];if(ptcb==(OS_TCB*)0){/*Tasktosuspendmustexist*/OS_EXIT_CRITICAL();return(OS_TASK_RESUME_PRIO);}if((ptcb->OSTCBStat&OS_STAT_SUSPEND)!=OS_STAT_RDY){/*Taskmustbesuspended*/if(((ptcb->OSTCBStat&=~OS_STAT_SUSPEND)==OS_STAT_RDY)&&/*Removesuspension*/(ptcb->OSTCBDly==0)){/*Mustnotbedelayed*/OSRdyGrp|=ptcb->OSTCBBitY;/*Maketaskreadytorun*/OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;OS_EXIT_CRITICAL();OS_Sched();}else{OS_EXIT_CRITICAL();}return(OS_NO_ERR);}OS_EXIT_CRITICAL();return(OS_TASK_NOT_SUSPENDED);}

885.任务睡眠

使当前任务睡眠一段指定的时间,时间到后,任务又重新回到就绪状态。任务睡眠通常需要进行以下工作:修改任务状态,把任务状态变为等待状态把任务TCB放置到时间等待链进行任务调度896.关于任务扩展

任务扩展便于应用能够向系统中添加一些关于任务的附加操作为应用提供在系统运行的关键点上进行干预的手段可把应用提供的函数挂接到系统中去在创建任务、任务上下文发生切换或是任务被删除的时候这些被挂接的函数能够得到执行90关于任务扩展

任务扩展的时机通常包含以下情况:任务创建时任务删除时任务上下文切换时任务扩展功能实现方式:任务扩展表

应用编程接口91任务扩展表处理

typedefvoid(*extensionRoutine)(void);typedefstruct{ extensionRoutineextensionOfTaskCreate; extensionRoutineextensionOfTaskDelete; extensionRoutineextensionOfTaskSwitch;}taskExtensionTable;statusCodeextensionCreate(taskExtensionTable*extensionTable,int

statusCodeextensionDelete(intextensionTableID);在任务扩展表处理方式中,任务扩展表用来存放实现任务扩展处理的例程,实时内核通过查找任务扩展表来获取扩展处理的入口函数。通过创建任务扩展表,把任务扩展例程添加到系统中去,通过删除任务扩展表则可把任务扩展例程删除掉。

92为任务创建、任务删除和任务上下文切换分别提供了添加和删除任务扩展处理例程。

API 描述extensionRoutineOfTaskCreateAdd(); /*为任务创建时提供扩展处理例程*/extensionRoutineOfTaskCreateDelete(); /*删除为任务创建提供的扩展处理例程*/extensionRoutineOfTaskDeleteAdd(); /*为任务删除时提供扩展处理例程*/extensionRoutineOfTaskDeleteDelete(); /*删除为任务删除提供的扩展处理例程*/extensionRoutineOfTaskSwitchAdd(); /*为任务上下文切换时提供扩展处理例程*/extensionRoutineOfTaskSwitchDelete(); /*删除为任务上下文切换提供的扩展处理例程*/通过单独的API实现任务扩展

93HOOKinucOS

voidOSIntCtxSw(void);voidOSStartHighRdy(void);voidOSTaskCreateHook(OS_TCB*ptcb);voidOSTaskDelHook(OS_TCB*ptcb);voidOSTaskStatHook(void);OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16Uopt);voidOSTaskSwHook(void);voidOSTimeTickHook(void);94HOOKusedinOSInitinucOS

voidOSInit(void){ OSInitHookBegin();/*Callportspecificinitializationcode*/ OS_InitMisc();/*Initializemiscellaneousvariables*/ OS_InitRdyList();/*InitializetheReadyList*/ OS_InitTCBList();/*InitializethefreelistofOS_TCBs*/ OS_InitEventList();/*InitializethefreelistofOS_EVENTs*/ OS_InitTaskIdle();/*CreatetheIdleTask*/ OSInitHookEnd();/*Callportspecificinit.code*/

955.4任务调度

基于优先级的可抢占调度时间片轮转调度静态调度*动态调度*静态调度与动态调度之间的比较*96任务调度要解决的问题WHAT:按什么原则分配CPU任务调度算法HOW:如何分配CPU任务调度的时机WHEN:何时分配CPU

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论