OSEK任务管理

1 前言

RTOS通过任务(task)来组织应用层程序框架(framework),支持任务的并发和同步执行(concurrent and asynchronous execution of tasks),并通过调度器(scheduler)来管理任务的执行,OSEK也概莫能外。

OSEK将任务划分为基础任务(basic tasks)和拓展任务(extended tasks)两类。对于基础任务来说,它们会一直占有CPU,直至其主动终止(terminate)任务运行,或被高优先级的任务/中断抢占,才会释放CPU资源;而拓展任务的特殊性在于多了一个可阻塞的等待状态,即任务阻塞在那里等待一个事件的触发(WaitEvent,如等待一个队列的入队操作等),这一状态被称为等待状态(waiting state)

拓展任务的等待状态的好处显而易见,即可以让出CPU资源给优先级较低的任务,但从OS的角度来看,相对于基础任务,其消耗的资源必然也更大,毕竟进入阻塞的等待状态前,需要对该拓展任务进行现场保护,这存在着时间和空间上的开销。

2 任务状态机模型

2.1 状态模型

如图1所示,基础任务和拓展任务的区别主要在于waiting状态(等待态/阻塞态),而running(运行态),suspended(挂起态)和ready状态(就绪态)的定义完全相同。显然,由于基础任务没有等待状态,因此只包含任务开始和结束时这两个同步点(synchronisation point);对于有内部同步点的作业,还是拓展任务更能胜任。

图1(a) 状态模型示意图

图1(b) 状态模型示意图

此外,为了降低系统复杂度,OSEK规定只有任务本身可以终止自己(self-termination),如果一个任务调用ChainTask来链式激活自己,则会将自己加到对应优先级的就绪态队列尾部,等待调度执行;同时,没有从挂起态到等待态的直接转换路径,在挂起状态下,任务处于被动状态,即可以被激活。

调度器(scheduler)根据调度策略(scheduling policy)来决定各任务的状态,选择当前得以运行的任务(使之从ready状态进入running状态),并为其统筹所有系统资源。从某种意义上,调度器本身也可以看作一种资源,在单核环境下,在同一时刻最多只能被一个任务占有,其本质是对应着CPU的计算资源。

2.2 任务优先级

OSEK完全摒弃了动态设置任务优先级的方式,采用静态方式配置任务优先级,即不可再运行时更改任务优先级。0是最低任务优先级,数值越大,则代表优先级越高,这点与freeRTOS相同,与ARM中断优先级定义方式相反。

此外,在BCC2或ECC2下,支持多个任务配置相同优先级。

2.3 调度策略

2.3.1 完全抢占式调度(Full preemptive scheduling)

简单来说,完全抢占式调度只有一个规则,就是完全按照优先级来进行调度,谁的优先级高,谁就执行。正在运行的任务必须做好随时被拉下神坛的觉悟,一旦有优先级更高的任务出现,则必须退位让贤(保存上下文,退回就绪态,让出CPU)。这种随时随地可能发生的重调度也就意味着,任务间的共享数据必须做好同步,否则必有惊喜出现。

总的来说,重调度点(触发系统调度)主要包括以下几种情形:

① 通过系统服务TerminateTask 成功终止一个任务时,或通过系统服务ChainTask成功终止当前任务并激活下一个任务时;

② 任务级别的任务激活(Activating a task at task level),包括通过系统服务ActivateTask

激活任务、通过消息通知机制(message notification mechanism)激活任务、或定时器溢出(alarm expiration)来激活任务等;

③ 在拓展任务中调用系统服务WaitEvent时,任务进入等待状态;

④ 设置一个事件(event)以唤醒等待该事件的任务,事件的设置可以通过系统服务SetEvent或通过消息通知机制或在定时器溢出处理中来实现;

⑤ 任务级别的资源释放(通过系统服务ReleaseResource);

⑥ 从中断返回任务时(Return from interrupt level to task level);

⑦ 显式调用系统服务函数Schedule时,触发调度。

2.3.2 非抢占式调度

该调度策略完全依赖于基于系统服务的显示调用来触发调度。在此策略下,任务的优先级显然也没多大意义了,高优先级的任务无法抢占低优先级的任务,只能等待低优先级任务主动让出CPU,这对于实时系统来说,显然时不利的。

非抢占式调度的重调度点主要包括以下几种情形:

① 通过系统服务TerminateTask 成功终止一个任务时,或通过系统服务ChainTask成功终止当前任务并激活下一个任务时;

② 显式调用系统服务函数Schedule时,触发调度;

③ 任务陷入等待状态,通常都是等待一个事件导致的(WaitEvent),其本质是任务被迫让出CPU的使用权。

2.3.3 任务组(Groups of tasks)

OSEK支持对任务进行分组,以分别执行抢占式调度策略和非抢占式调度策略。具体来说,对于那些优先级小于等于组内最高优先级(the highest priority within a group)的任务,执行非抢占式调度策略(non preemptable tasks);对于那些优先级大于组内最高优先级的任务,执行抢占式调度策略。

这么做有什么好处呢?一个典型的例子,可以将共享同一资源的任务分在一组内,而当任何组内占有这一共享资源时,都会通过优先级提升将任务优先级临时设置为资源的上限优先级 (天花板优先级,ceiling priority of the resource),这会避免不必要的任务抢占和调度,毕竟共享资源本事就是临界资源。另一方面,对于那些优先级高于上限优先级且不需要该资源的任务,仍以抢占式调度策略来执行。

2.3.4 混合式抢占调度策略(Mixed preemptive scheduling)

当系统上同时存在可抢占和不可抢占任务时,就需要应用混合式抢占调度策略。在这种情况下,会为任务添加上是否可抢占的属性标签,并在运行时执行对应的调度策略。这也就意味着,系统中的任务存在两种不同调度类型,即可抢占和不可抢占(preemptable or non preemptable),这与任务类型(task type,基础任务和拓展任务)是相互独立的、不同维度的概念。

在完全抢占式调度策略里混合点不可抢占的刺头的意义在哪呢?首先,如果一个任务的执行时间很短,短到同切换上下文(任务切换)的耗时接近,甚至更短,那就没必要抢占这个任务,让它执行结束好了;其次,不抢占意味着不用做上下文切换,也就省去了现场保护的内存开销,这对于RAM的节约相当友好;最后,也有可能存在一些这样那样的任务,人家本身就是不希望被抢占的。

相关推荐
汽车仪器仪表相关领域10 天前
动态诊断充电中枢:DCA-8000型动态诊断充电系统 4S店/维修连锁/新能源服务站/车队维保全场景实战全解
人工智能·车载系统·汽车·负载均衡·压力测试·可用性测试
杰克崔10 天前
android的lmkd的实现及代码分析
android·linux·运维·服务器·车载系统
进击的横打13 天前
【车载开发系列】入坑RH850芯片
c语言·车载系统
进击的横打13 天前
【车载开发系列】GPIO核心概念理解
车载系统
进击的横打15 天前
【车载开发系列】Renesas Flash Programmer (RFP) 反向读取功能
车载系统·编辑器·rfp
进击的横打16 天前
【车载开发系列】瑞萨RH850芯片基础介绍
车载系统
进击的横打18 天前
【车载开发系列】Renesas Flash Programmer (RFP) 使用教程
车载系统
进击的横打19 天前
【车载开发系列】浮点数与整型数的转换
c语言·车载系统
进击的横打20 天前
【车载开发系列】C语言浮点数入门
c语言·车载系统
王夏奇22 天前
自动泊车技术-入门理解
车载系统