OSEKOS task管理

发布时间:2026/7/30 3:47:51

OSEKOS task管理 2 task管理2.1 task概念task为函数们的执行提供了框架。操作系统提供task的并发和异步执行。scheduler组织task执行的顺序。操作系统提供了一种task切换机制(参见scheduler)包括一种在没有其他系统或应用程序功能处于活动状态时处于活动状态的机制。这种机制称为空闲机制。操作系统提供了两种不同的task概念:基本task;扩展task。2.2 task状态模型12.2.1 General一个task应该能够在多个状态之间变化因为处理器在任何时候只能执行一个task的一条指令而多个task可能在同一时间竞争处理器。操作系统负责在必要时连同task状态转换一起保存和恢复task上下文。2.2.2 基本task基本task由以下task状态组成:运行Running: 在运行状态下task被分配给CPU使其指令可以执行。在任何时间点只有一个task处于该状态而其他所有状态可以被多个task同时采用。就绪Ready: 转换到运行状态的所有功能先决条件都已经存在task只等待处理器的分配。scheduler调度器决定接下来执行哪个Ready的task进入Running。挂起Suspended: task为被动状态可被激活只有被激活到Ready才能到Running。只有当task自己终止(“self- terminate”)时才有可能终止task。这个限制降低了操作系统的复杂性。所以每次task的最后都需要调用接口来让出CPU资源。基本task只有在以下情况下才会释放处理器:他们自己终止;操作系统切换到更高优先级的task;或一个中断发生导致处理器切换到一个中断服务程序(ISR)。可以如下定义一个基础task其他触发源触发了激活task有以下两种方式 { ActivateTask(Base_demo1); 或者 ChainTask(Base_demo1); } task(Base_demo1) { code_1; // 每次从ready到running状态时,都是从头code_1开始往下运行 code_2; // 此处被中断或者更高优先级的task抢占,待他们运行完成之后,继续执行code_3 code_3; code_4; TerminateTask(); // 结束当前task_Base_demo1运行 或者 ChainTask(task_Base_demo2); // 结束当前task_Base_demo1运行,并且切换到 other_task 运行 }2.2.3 扩展task扩展task与基本task的区别在于允许使用OS WaitEvent这可能会导致等待状态。等待状态允许释放处理器并将其重新分配给低优先级的task而不需要终止正在运行的扩展task。从操作系统的角度来看扩展task的管理在原则上比基础task的管理更加复杂需要更多的系统资源。因为切入到等待状态之后会把当前task的堆栈信息保存起来。扩展task有四种task状态比基础Task多一个Waiting:等待: task不能继续执行因为它必须等待至少一个事件(后续章节描述)。不提供从挂起状态到等待状态的直接转换。这种转换是多余的会增加调度器的复杂性。可以如下定义一个扩展task其他触发源触发了激活task有以下两种方式 { ActivateTask(Extend_demo1); 或者 ChainTask(Extend_demo1); } task(Extend_demo1) { code_1; // 每次从ready到running状态时,都是从头code_1开始往下运行 code_2; // 此处被中断或者更高优先级的task抢占,待他们运行完成之后,继续执行code_3 code_3; code_4; WaitEvent(Event_XXX|Event_YYY); // 此处可以 WaitEvent 等待 Event_XXX 或者 Event_YYY 事件,之后进入waiting状态直到其中一个发生 // 等待到了其中一个事件task变化为ready状态调度器开始运行之后的代码逻辑。 GetEvent(TaskId_Extend_demo1, ev); // 获取当前TASK的事件合集 if ((ev Event_XXX) ! (EventMaskType)0) // 发生事件 Event_XXX { ClearEvent(ev (Event_XXX)); // 清除对应的事件 code_5; } if ((ev Event_YYY) ! (EventMaskType)0) // 发生事件 Event_YYY { ClearEvent(ev (Event_YYY)); // 清除对应的事件 code_6; } code_7; TerminateTask(); // 结束当前task_Base_demo1运行 或者 ChainTask(task_Base_demo2); // 结束当前task_Base_demo1运行,并且切换到 other_task 运行 } 其他触发事件触发了激活task { SetEvent(Event_XXX); 或者 SetEvent(Event_YYY); 或者 SetEvent(Event_XXX|Event_YYY); }逐一分析task的运行状态task初始化之后初始状态是Suspended执行激活activate之后状态由 suspended改变为ready放入调度器中进行排队等着运行OS保证task是由这个task的第一句指令开始执行的。之后调度器选用了这个task便start这个task把CPU资源交给它由ready状态到running状态开始正式运行。如果在task运行过程中需要某个事件才可以继续往下运行那么这个task可以调用WaitEvent开始wait事件交出当前CPU资源状态由Running变为Waiting如果等待到了需要的Event那么就release释放当前的Waiting状态变为ready状态再接着等待调度器选用是否执行这个task。以上running到waiting到ready状态只有扩展task有。如果在当前task运行过程中被更高优先级的taskpreempt抢占状态由running到ready会保存当前的堆栈状态等待调度器选用选用了之后恢复堆栈状态继续执行之前的代码。如果在当前task运行结束了 terminate终止 需要自己调用TerminateTask表示跑完了由running到suspended等待被激活。调用TerminateTask不一定在task的最后哦也可以在中间某个条件满足了之后他表示的是当前的动作执行完成了可以不需要CPU了2.2.4 task类型的比较基本task没有等待状态因此只包含task开始和结束的同步点。具有内部同步点的application parts应由多个基本task实现。基本task的一个优点是它们对运行时上下文(RAM)的需求适中。扩展task的一个优点是无论哪个同步请求是活动的它们都可以在单个task中处理一致的作业。当需要进一步处理的当前信息缺失时扩展task将切换到等待状态。当相应的事件发出接收或更新所需数据或事件的信号时它将退出此状态。扩展task还包含比基本task更多的同步点。可以理解为扩展task比基础task多了一个同步的功能等待某个Event之后再运行。2.3 激活一个task2.3.1 Generaltask激活通过操作系统服务ActivatTask或ChainTask进行。激活后task就可以从第一条语句开始执行了。操作系统在启动task时不支持类c参数传递。这些参数应该通过消息通信(参见后面章节)或全局变量传递。需要注意的是task是没有周期运行的属性如果需要达到周期运行那么就是对应激活task这个动作周期执行便达到了周期运行task的需求。2.3.2 task激活的多个请求根据一致性类的不同基本task可以被激活一次或多次。“task激活的多个请求”意味着操作系统接收并记录一个已激活的基本task的并行激活。如果未达到多个请求的最大数量则请求将进入队列。并行多个请求的最大数量在系统生成期间在一个基本task特定属性中定义。基本task激活的请求按激活顺序按优先级排队。相当于给这个基础task定义了一个FIFO并且这个FIFO的优先级就是对应基础task的优先级调度器会根据优先级先判断释放需要执行这个FIFO中的基础task并根据先被激活的顺序执行这个基础task。2.4 task切换机制决定启动哪个task和触发所有必要的操作系统内部活动的实体被称为“scheduler调度器”。根据所述的调度策略只要有可能进行task切换就激活所述 scheduler。scheduler 可以被看作是一种可以被task占用和释放的资源。因此task可以保留scheduler以避免task切换直到它被释放(后续6.4描述这个资源叫做RES_SCHEDULER )。2.5 task优先级scheduler 根据task优先级来决定哪个task是下一个要转移到 running 状态的 ready task。0被定义为task的最低优先级。因此数字越大优先级越高。为提高效率不支持动态优先级管理。因此task的优先级是静态定义的即用户在运行时不能更改task的优先级。但是在特定情况下OS可以处理具有定义的更高优先级的task(看后续资源天花板机制6.6章节)。一致性类BCC2和ECC2支持具有相同优先级的task。具有相同优先级的task根据其激活顺序启动处于等待状态的扩展task不会阻塞具有相同优先级的后续task的启动。被抢占的task被认为是其当前优先级的就绪列表中的第一个(最早的)task。比如task1和task2优先级是4task3优先级是8且都是可抢占先激活了task1再激活task2都是ready状态scheduler选择task1先到running在运行途中被task3被激活scheduler立马把task1保存堆栈切换到ready状态把task3切换到runningtask运行完成之后scheduler寻找处于ready状态的task发现有task1和task2但是由于task1是之前scheduler切换抢占运行的所以先running task1task1运行完成之后再运行task2.从等待状态释放的task将被视为其优先级就绪队列中的最后一个(最新的)task。比如task1和task2和task3优先级是4且都是可抢占先激活了task1是ready状态scheduler选择task1先到running在运行途中被task1需要等待一个事件进入waiting状态之后一起Event到达和激活task2task3scheduler会先运行task2再task3最后才是task1.图6显示了使用每个优先级级别的队列实现scheduler的示例。几个优先级不同的task处于就绪状态;即三个优先级为3的task一个优先级为2一个优先级为1再加上两个优先级为0的task。根据请求的顺序等待时间最长的task显示在每个队列的底部。处理器刚刚处理并终止了一个task。scheduler选择要处理的下一个task(优先级3第一个队列)。在处理优先级2的task之前所有高优先级的task都必须处于运行就绪状态即启动然后由于终止或过渡到等待状态而从队列中移除。以下基本步骤是确定下一个要处理的task所必需的:调度器搜索所有处于就绪/运行状态的task。从处于就绪/运行状态的task集中scheduler确定具有最高优先级的task集。在处于就绪/运行状态且优先级最高的task集中scheduler找到最早的task。2.6 调度策略2.6.1 全抢占式调度 Full Preemptive Scheduling完全抢占式调度是指当前正在运行的task可以根据操作系统预先设定的触发条件在任何指令下重新调度。一旦高优先级的task就绪完全抢占式调度就会将正在运行的task置于就绪状态。task上下文被保存以便被抢占的task可以在它被抢占的位置继续执行。完全抢占式调度的延迟时间与低优先级task的运行时间无关。某些限制与节省上下文所需的(RAM)内存空间的增加以及task之间同步所需特性的复杂性的增强有关。由于理论上每个task都可以在任何位置重新调度因此与其他task联合使用的数据访问需要同步。在图7中低优先级taskT2不会延迟高优先级taskT1的调度。在完全抢占系统的情况下用户应该想象到正在运行的task在任意时刻被抢占。如果一个task片段不能被抢占可以通过系统服务 GetResource 暂时阻塞scheduler来实现。综上所述在以下所有情况下都会执行重调度:成功终止task(系统服务TerminateTask11.3.2章节);通过显式激活后继task成功终止task(系统服务ChainTask11.3.2章节);在task级别激活task(如系统服务 Activatetask11.3.2章节消息通知机制Alarm过期;如果定义了task激活7.3章节);显式wait调用此时系统会发生向Waiting状态的转换(仅扩展task、系统服务 WaitEvent11.6.2章节);设置事件为task级别的等待task(如系统服务 SetEvent11.6.2章节消息通知机制Alarm过期;如果事件设置已定义7.3章节);task级资源释放( 系统服务ReleaseResource 11.5.2章节);从中断级返回到task级。在ISR中断服务例程中不执行重调度。因为ISR中不属于可调度上下文一旦跳出去就回不来了使用“完全抢占式调度”调度策略的应用不需要系统服务Schedule而其他调度策略使用该系统服务。为了使可移植的应用程序能够在不同的调度策略下编写用户可以通过系统服务Schedule在用户认为正确的CPU分配的位置执行重新调度。2.6.2 非抢占式调度如果task切换只通过一个显式定义的系统服务(显式重调度点)来执行则调度策略被描述为非抢占式。非抢占式调度对task的可能时序要求施加了特殊的限制。具体来说运行中的低优先级task的不可抢占部分将高优先级task的开始延迟到下一个重调度点。在图8中优先级较低的taskT2将优先级较高的taskT1延迟到下一个重调度点(在本例中taskT2终止)。2.6.3 重调度点对于非抢占task重调度应在以下情况发生:task成功终止(系统服务 Terminatetask11.3.2章节)。通过显式激活后继task成功终止task(系统服务ChainTask11.3.2章节)。显式调用scheduler(系统服务Schedule11.3.2章节)。当前task发生了向Waiting状态的转换(系统服务WaitEvent11.6.2章节)。如果传递给WaitEvent的事件掩码中有一个事件已经设置WaitEvent的调用不会导致等待状态。在这种情况下WaitEvent不会导致重新调度。非抢占式系统的实现可能规定导致重调度的操作系统服务只能在最高的task程序级别调用(而不是在task子函数中)。注: 在这些调度点上的task切换通常需要保存较少的task上下文信息。2.6.4 task组OS允许task通过定义task组来结合抢占式调度和非抢占式调度。对于与组内最高优先级相同或更低优先级的task组内task的行为类似于不可抢占的task: 重调度只发生在4.6.2中所述的重调度点。对于优先级高于组内最高优先级的task组内task的行为类似于可抢占task。内部资源章节描述了使用内部资源定义组的机制。非抢占性task是内部资源概念最常见的用法;它们是具有特殊内部资源的task具有最高的task优先级。2.6.5 混合抢占调度如果在同一个系统上混合使用可抢占和不可抢占的task则产生的策略称为“混合抢占”调度。在这种情况下调度策略取决于正在运行的task的抢占属性。如果正在运行的task是非抢占式的则执行非抢占式调度。如果正在运行的task是可抢占的则执行抢占调度。非抢占task的定义在全抢占操作系统中是有意义的:如果task的执行时间与task切换的时间大小相同;如果要经济地使用RAM来提供空间以保存task上下文;如果task没有被抢占的需求。许多应用程序只包含几个执行时间很长的并行task对于这些task完全抢占式操作系统会很方便。而许多具有确定执行时间的短task时非抢占式调度会更有效。对于这种配置混合抢占式调度策略是一种折衷(参见14.3.5中的设计提示)。2.6.6 选择调度策略软件开发人员或系统集成商通过配置task优先级和将可抢占性作为task属性来确定task的执行顺序。task类型(基本或扩展)独立于task的调度类型(可抢占或不可抢占)。因此完全抢占式系统可以包含基本task和非抢占式系统扩展task。如果OS服务正在运行抢占和上下文切换可能会延迟到服务完成。2.7 task的终止在操作系统中task只能自行终止(self- terminate)。操作系统提供了ChainTask服务保证在一个正在运行的task结束后立即激活执行另一个特定task。Chain本身会将task放到优先级队列的最后一个元素中。每个task都将在其代码结束时自行终止。当task结束时调用Terminate task或ChainTask;不这样做会导致未定义的行为。

相关新闻