RTA OS系列介绍01-Task

电子说

1.3w人已加入

描述

 

0. 系列概述

OSEK是由欧洲自动化协会对汽车电气制定的开放式系统,全称为OS-EK/VDX。

RTA-OS是基于OSEK OS的符合AUTOSAR规范的OS,是一种静态可配置、抢占式、实时操作系统(RTOS),用于高性能、资源受限的应用程序。

AUTOSAR OS主要包含Task, ISRs, Events, Resources, Application, Counter, Alarms, Schedule Table等OS对象。后续将对如上提到的八个对象进行分别介绍,本篇介绍的内容为Task,下面进入正题:

 

1.Task概述

任务调度分为静态调度及动态调度,二者区别为,静态调度是在调度前就已经配置好,而动态调度是根据负载率自动去调度的。在OSEK的OS系统中,Task是主要部分,RTOS里是静态调度,在单个处理器上一次只运行一个任务,不同任务之间通过调度表或者Alam进行切换。

 

2. 基本概念

2.1 基础任务与扩展任务

当前项目中基本使用的都是BASIC类型。

 

2.1.1 基础任务

状态:Running,Ready,Suspended。

基本任务开始、执行和终止(这通常称为单次任务模型)。只有当基本任务终止或被更高优先级的任务抢占时,它才会释放处理器。这种行为使它们非常适合嵌入式控制功能。基本任务快速有效。

 

2.1.2 扩展任务

扩展任务启动、执行、等待事件(Wait event)和(可选)终止。扩展任务在执行期间自动挂起自身任务的能力为任务提供了一种具有同步点的方法。此功能使扩展任务比基本任务更适合于需要中间执行同步的功能。 

扩展任务时间响应较快,但会一直占用Ram资源,相当于以空间换时间。

OSEK

2.2 任务状态

任务的状态包括:Ready、Running 、(Waiting) 、Suspended

所有任务默认的状态都是Suspended状态,在被激活后才变成Ready状态,当该任务为系统中的最高优先级任务时即转为Running状态,并开始执行任务,同时任务可能被更高优先级的任务抢占,重新变成Ready状态。

 

任务通过终止返回到挂起(Suspended)状态。一项任务可以在以后再次准备好,整个过程可以重复。

 

但是,扩展任务也可以进入Waiting状态。当扩展任务通过等待事件自动挂起时,它将从Running状态移动到Waiting状态。

当扩展任务进入Waiting状态时,操作系统将分派准备运行的最高优先级任务。设置事件后,任务将从Waiting状态移动到Ready状态。请注意,扩展任务返回到Ready状态,而不是Running状态。这是因为,在扩展任务处于Waiting状态期间,其他一些更高优先级的任务可能已被激活,然后被调度。

Event只是用于为系统事件提供指示器的操作系统对象。事件示例包括数据准备好使用或正在读取传感器值。

激活Task的方式有:调用ActivateTask() API,或Alarm到期或调度表

 

2.3 任务优先级

AUTOSAR-OS运行任务可以享有同一优先级,同一优先级的任务以先进先出FIFO(First In First Out)的原则从Ready状态Release。

使用时需避免使用Share Priorities,实时性差,无法进行调度可行性分析。

 

2.4 任务激活

2.4.1 队列任务激活

在大多数情况下,仅需任务处于挂起状态时激活它。事实上,AUTOSAR OS将处于就绪、运行或等待状态的任务激活视为错误情况。

但是,在某些情况下,可能需要实现一个系统,该系统必须多次激活同一任务,但连续激活之间最短的时间可能小于运行该任务所需的时间。例如,用户可能正在任务中解包CAN总线帧,并且需要处理网络上帧的瞬时突发,这意味着用户需要在运行时对任务激活进行排队。

AUTOSAR OS允许对基本任务的激活进行排队,以帮助构建此类应用程序。与AUTOSAR OS中的其他功能一样,任务队列的大小是静态配置的。必须指定任务可以挂起的最大激活次数。如果超过激活的最大次数,激活将被忽略。

 

2.4.2 异步任务激活

AUTOSAR OS允许别的核激活当前核的Task,而不是从任务实际运行的核激活任务。虽然这可能很有用,但可能会影响性能.因为要完全符合AUTOSAR,所有任务激活(包括SetEvent)必须阻止调用方,直到任务状态更新。在内部,操作系统必须使用内部自旋锁来协调与所属核的状态更改。这会对所有核的性能产生重大影响。

 

2.5 任务调度

RTA-OS提供了一种根据提前固定好的不同优先级的任务间切换执行的调度方式。优先级排序的原则一般为:执行时间越短,执行频率越快的优先级越高。但无论选择如何分配优先级,任务执行的顺序都由调度策略决定。调度策略确定任务实际运行的时间,AUTOSAR OS支持两种调度策略:

 

2.5.1 抢占式调度

当一个Task正在运行,另一个更高优先级的任务准备运行,此时高优先级的任务会抢占执行,这也被称为任务切换,高优先级任务执行完毕后,原来的task继续执行。 

OSEK

2.5.2 非抢占式调度

与抢占式调度不同的是,如果高优先级任务准备就绪,那么它将保持准备运行状态,直到运行任务终止—它不会抢占。这意味着开始运行的非抢占式任务将始终运行到完成,然后终止。 

OSEK

2.5.3 协作式调度

此外,AUTOSAR OS提供了对第三种称为协作调度的调度的支持,因为它允许非抢占式任务告诉OS何时可以抢占。之所以说AUTOSAR OS支持两种策略,是因为只有两种配置—第三种配置必须自己构建。 

 

操作系统运行准备运行的最高优先级任务。如果更高优先级的任务准备就绪,那么它将保持就绪,直到以下任一情况:

1) 正在运行的任务终止(就像非抢占式调度一样);

2) 或者正在运行的任务发出Schedule()API调用,告诉操作系统它可以被抢占。

 

当发出Schedule()调用时,优先级较高的任务会抢占正在运行的任务,当高优先级任务完成后,抢占任务将恢复。这种合作模式提供的系统虽然不如完全抢占式系统响应快,但不会出现非抢占式调度缺乏响应的情况。

OSEK

3. Task 配置

包括:name、Priority、Scheduling、Activation及Autostart

优先级:0是最低优先级,

调度:任务可以完全抢占或非抢占地运行。一般来说,为了获得最佳的应用程序性能,应该选择完全抢占式调度而不是非抢占式调度。

激活:在Ready状态下可以排队的最大任务激活数。对于BCC1、ECC1和ECC2任务,激活次数始终为一次。这意味着这些类型的任务只有在处于挂起状态时才能激活。在未挂起的情况下,尝试激活此类任务将导致错误。大于1的值表示操作系统将对激活进行排队,任务结束时再次激活。

 

4. 堆栈管理

RTA-OS使用单栈模型,即所有的Task、ISRS在同一个堆栈区域上运行。

 

当任务运行时,其堆栈使用量会像正常情况一样增减。当任务被抢占时,高优先级任务的堆栈使用将在同一堆栈上继续(就像标准函数调用一样)。当任务终止时,它使用的堆栈空间将被回收,然后重新用于下一个优先级最高的任务运行(同样,与标准函数调用一样)。下图显示了单堆栈在声明、抢占和终止任务时的行为。 

OSEK

在单堆栈模型中,堆栈大小与系统中优先级的数量成比例,而不是与任务/ISR的数量成比例。这意味着,直接或通过共享内部资源,或通过被配置为非先发制人,共享优先级的任务永远不会同时出现在堆栈上。在硬件上共享优先级的ISR也是如此。这意味着用户可以通过简单的配置更改来交换系统响应性,即任务或ISR完成所需的时间,以换取堆栈空间。 

 

上图显示了同一任务集的执行情况,具有与上上图相同的到达模式,但这次任务是非抢占式调度的。可以看到,高优先级任务的响应时间比抢占式调度时长得多,但总体堆栈消耗要低得多。

OSEK

单堆栈模型还显著简化了链接时的堆栈空间分配,因为用户只需为整个系统堆栈分配单个内存部分,就像根本不使用操作系统一样。

 

4.1 扩展任务的堆栈管理

RTA-OS独特地扩展了单堆栈模型,在不影响基本任务性能的情况下为扩展任务提供支持。在RTA-OS中,扩展任务的生命周期如下:

Suspended→Ready:任务被添加到Ready 序列

Ready→Running:任务已调度,但与内容位于堆栈顶部的基本任务不同,内容位于堆栈空间中,所有低优先级任务的预先计算的最坏情况抢占深度处。

 

Running→Ready:扩展任务被抢占。如果抢占任务是一个基本任务,那么它会像往常一样在堆栈顶部调度;如果抢占任务是一个扩展任务,那么它将按照预先计算的所有低优先级任务的最坏情况抢占深度进行调度。

 

Running→Waiting:任务的等待事件堆栈内容(包括操作系统上下文、本地数据、函数调用的堆栈帧等)保存到内部操作系统缓冲区中。

 

Waiting→Ready:任务添加到Ready 队列。

 

Running→Suspended:任务的“等待事件堆栈”内容将从内部操作系统缓冲区复制回堆栈中所有低优先级任务预先计算的最坏情况抢占深度。 

OSEK

扩展任务管理要求RTA-OS知道任务和ISR使用了多少堆栈。以下各节描述了各种配置参数。

 

4.2 处理堆栈溢出

如果用户提供给RTA-OS的堆栈分配太小(运行时错误的潜在来源),有三种错误情况可能发生:

1.当RTA-OS尝试调度扩展任务时,堆栈指针的当前值高于计算的最坏情况调度点,因此扩展任务无法启动。这意味着堆栈上的一个(或多个)低优先级任务占用了太多空间。

 

2.扩展任务无法从等待状态恢复,因为堆栈指针高于它应该的值。当为扩展任务正在等待的事件调用SetEvent()并且扩展任务现在是系统中优先级最高的任务时,可能会发生这种情况。

 

3.扩展任务无法进入等待状态,因为任务正在使用的堆栈的当前数量大于配置的“WaitEvent()堆栈”的大小。

 

当RTA-OS检测到扩展任务堆栈管理出现问题时,它将调用ShutdownOS(),错误代码为E_OS_STACKFAULT。如果要调试该问题,则可以启用堆栈故障Hook。配置后,RTA-OS将在堆栈故障发生时调用用户提供的回调OS_Cbk_StackOverflowHook(),而不是ShutdownOS()。回调传递了两个参数:溢出的字节数、溢出的原因。

 

5. 任务的控制

5.1 任务激活

任务激活后变为Ready状态,当该任务的优先级为所有Ready状态的任务及当前处于Running的任务最高时,开始(或抢占)变成Running状态。

任务每次被激活后会运行一次,当激活的次数超过配置次数时会报E_OS_LIMIT错误。

任务可以通过Tasks或二类中断激活。

 

5.1.1 直接激活

可以通过多种不同的方式激活任务。任务激活的基本机制是ActivateTask()API调用,它直接激活任务。ActivateTask(TaskID)调用将命名任务置于就绪状态。ChainTask(TaskID)终止当前正在运行的任务,并将激活指定任务置于就绪状态。

#include  


TASK(Task1)  {


  /*  Task1  functionality.  */


  ActivateTask(Task2);


  TerminateTask();


}


TASK(Task2)  {


  /*  Task2  functionality.  */


  ActivateTask(Task3);


  TerminateTask();


}


TASK(Task3)  {


  /*  Task3  functionality.  */


  TerminateTask();


}

5.1.2 间接激活

通过Alarm激活或通过调度表激活。

通过Alarm激活:对于系统中的每个Alarm,可以指定一个任务,该任务在每次Alarm过期时激活。

调度表激活:对于系统中的每个调度表,可以指定在表上的一个或多个到期点激活的任务。

 

5.2 任务执行顺序控制

许多情况下,需要控制任务执行的顺序,即某个任务的执行需要基于前一个任务执行的结果。时序的控制可以通过如下三种方式:

•直接激活链;

•优先级;

•不可抢占的任务。

 

5.2.1 通过直接激活链

当使用直接激活链控制执行顺序时,任务对必须在发出调用的任务之后执行的任务进行ActivateTask()调用。 

OSEK

5.2.2 通过任务优先级

将需要优先执行的任务设置更高的优先级,在执行时即可按抢占式完成。

 

5.3 RTA-OS中的合作式调度

当任务以非抢占方式运行时,它会阻止任何任务(包括优先级较高的任务)执行。然而,有时对于非抢占式任务来说,提供可以进行重新调度的明确位置是很有用的。这比简单地非抢占式运行更有效,因为高优先级任务对系统刺激的响应时间更短。任务以非抢占方式运行并为重新调度提供点数

的系统称为合作调度系统。 

OSEK

5.4 任务终止

在AUTOSAR操作系统中终止的任务必须进行API调用,以告知操作系统正在发生这种情况。AUTOSAR OS标准定义了两个用于任务终止的API调用。其中之一必须用于终止任何任务。这些API调用是:

• TerminateTask()

• ChainTask(TaskID)

 

当任务完成时,它必须进行其中一个API调用。这确保RTA-OS可以正确地安排准备运行的下一个任务。

 

TerminateTask()强制调用任务进入挂起状态。RTA-OS将在Ready状态下运行下一个优先级最高的任务。

 

ChainTask(TaskID)终止调用任务并激活任务TaskID。因此,该API类似于执行TerminateTask(),然后立即执行ActivateTask(TaskID)。链接任务会将命名任务置于就绪状态。

 

5.5 任务的Idle机制

在任何抢占式OS中,当没有Task或中断运行时也必须要有些事情做。在AUTOSAR OS中是通过Idle 机制实现。在RTA-OS中当没有Task或中断执行时,系统将处于繁忙的等待循环中。

 

用户可以通过声明一个名为Os_Cbk_idle的回调函数来提供自己的空闲机制实现方式,从而覆盖默认行为。

Os_Cbk_idle的行为较普通Task外有如下不同:

 

. 不能被激活

. 不能被终止

. 不能被链(嵌套)调用

. 不能使用内部资源

 

Os_Cbk_Idle的优先级最低,即当没有任何及中断运行时才会Ready to Run。

Os_Cbk_Idle在退出时返回一个布尔值,告诉RTA-Os是否再次调用Os_Cbk_Idle。当返回TRUE时,RTA-OS将立即再次调用Os_Cbk_Idle。当返回FALSE时,RTA-OS停止调用Os_Cbk_Idle并进入繁忙等待循环的默认行为。

 

审核编辑 :李倩


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分