AUTOSAR OS总共包含以下6大基本对象:Counter,Alarm,Schedule Table,Task,ISRs,Resource。
Core中基本对象关系
如上图所示,以单核为例,每一个Core可包含1~N个OS Application,而每一个OS Application可包含0~N个基本对象。每个基本对象必须从属于某个OS Application,否则会出现错误。
同时OS Application可分为Trusted与Not Trusted这两种类型。
从属于Not Trusted OS Application的OS基本对象对存储器和API的访问将受到限制,通常会将一些基础软件的模式管理主函数映射到Not Trusted OS Application中的任务,如EcuM_Mainfunction,BswM_Mainfunction, Can_Mainfunction_Mode()等周期性状态查询函数,当然前提这些软件模块的安全级别为QM。
AUTOSAR OS中存在两种任务:基本任务(Basic Task)和扩展任务(Extended Task)。
基本任务与扩展任务的状态机切换如下图5所示:
图5 基本任务与扩展任务状态切换图
运行状态(Running):处于运行状态的任务可能被高优先级任务或者中断抢占从而进入就绪状态,且同一Core中任何时刻只会存在一个任务处于运行状态,任务运行结束后则将自己挂起进入阻塞状态;
就绪状态(Ready): 处于就绪状态的任务由调度器决定是否启动进入运行状态,且该状态时任务切换至运行状态的前提;
阻塞状态(Suspend): 处于阻塞状态的任务是被动的,可以由API函数或Alarm激活进入就绪状态;
扩展任务与之相比,则多了一个等待状态(Waiting),解释如下:
等待状态(Waiting): 当任务的运行需要等待某一或某些事件被置位时,任务进入就绪状态。
如上图所示,基本任务没有等待状态,所以只能在任务启动与终结时进行同步,基本任务的优点就是占用较小的任务与执行时间。
扩展任务的优点是包含多个同步点,没有同步请求的麻烦,当进一步的条件无法满足时,任务则会切换至等待状态,其缺点也很明显,会占用较多的内存和执行时间。
Task调度策略
AUTOSAR OS是基于优先级进行任务调度,所以每个任务必定有一个优先级,而每个任务都是根据其自身特点来定义一个优先级且需要配置其可抢占属性。
可抢占属性可分为不可抢占与全抢占,这里所说的抢占指的是内核抢占。AUTOSAR OS可根据各个任务的可抢占属性配置,来提供不同的调度策略,调度策略可分为以下三种:
完全抢占式:OS所有任务均是可抢占类型;
1.对于完全抢占式任务调度策略而言,当前运行的任务可在任何时刻被高优先级任务打断而被迫释放处理器控制权,具备最高优先级的任务从就绪状态转入运行状态,而当前任务被抢占从而进入就绪状态,同时保留现场环境,带下次运行时恢复。
如下图7所示为完全抢占式任务调度策略,TaskA为扩展任务,TaskB与TaskC为基本任务,优先级TaskA > TaskB > TaskC。
图7 完全抢占式调度策略
Case1:
当前TaskC处于运行状态,当激活TaskB进入到就绪状态时,由于TaskB优先级高于TaskC,所以TaskC被迫释放处理器控制 权,调度器 开始调度TaskB从就绪状态变为运行状态,直到TaskB运行完成之后,在调度TaskC继续运行。
Case2:
当前TaskC处于运行状态,激活TaskA与TaskB分别进入就绪状态,由于TaskA优先级高于TaskB,所以TaskA抢占内核运行, 但是由于Resource1仍被TaskC暂用,而TaskA无法访问到共享资源Resource1,则被迫进入到等待状态,TaskB开始运行。
TaskB运行结束后挂起之后则重新运行TaskC,TaskC运行结束后释放Resource1,进入TaskA得以由等待状态转入运行状态。此时你会 发现高优先级的任务TaskA由于共享资源被占用的原因导致不能先于TaskB运行的现象,该现象也被称为优先级反转现象。
为了解决该问题,在此需要提到AUTOSAR OS的优先级天花板模式:即将访问共享资源的任务优先级在占用资源的过程中提升至共享资 源任务的最高优先级之上,从而避免优先级反转现象的发生。
即若TaskC运行过程中占用共享资源Resource1,此时即使存在需占用共享资源的高优先级任务TaskA被激活,也必须保证TaskC运行结 束之后才能执行TaskA,也就意味着在重要代码执行之前,应采用资源保护机制,以免被高优先级的任务打断。
非抢占式:OS中所有任务均是不可抢占的;
2. 若采用非抢占式调度策略,那么当前运行状态的任务在任何时刻都不会其他高优先级任务所抢占,任务的切换只会发生在任务完时。 非抢占式调度策略的问题在于任务执行时间不确定,系统调度实时性较差。如下图8所示为非抢占式调度策略,可见即使高优先级任务 TaskB被激活切换至就绪状态,也必须等到TaskC执行结束之后才能够被调度。
图8 非抢占式调度策略
混合抢占式:OS部分任务是可抢占类型,部分任务是不可抢占类型;
3.若采用混合抢占式,则OS的调度策略就取决于当前任务的可抢占属性,如果为非抢占,则执行非抢占式调度策略,如果为抢占式则执 行完全抢占式调度策略。
Counter概念的引入是为了实现对硬件计数器以及软件计数器的管理,为Alarm与Schedule table提供支持。即多个Alarm可以共用一个Counter,一个Schedule Table只能由一个Counter来驱动。 Counter按照AUTOSAR定义可分为以下两种:
Hardware Counter: 该Counter的增加由硬件外设驱动,如Gpt或者timer等;
Software Counter: 该Counter的增加通过调用API函数IncrementCounter来实现,且每次只能增加1;
基本原则: 优先使用Hardware Counter,因为可以根据Task的激活状况来减少无意义的时钟中断;
如下图9所示,则较为清晰的表现了Counter,Schedule Table以及Alarm三者之间的关系。
在计数器的基础上,AUTOSAR OS为应用软件提供了闹钟机制,多个闹钟可以连接一个Counter,当到达Alarm所对应的计数器设定值时,则可以激活一个任务,设定一个event,调用callback或者增加计数器等功能,但只能是一对一。
不能像Schedule Table那样,能够在Expiry point同时设定多个Task或者多个Event,这也是为什么引入Schedule Table的原因。
一个软件Counter +多个Alarm队列就可以实现静态定义的任务激活机制。 但随着Schedule Table的引入,因此一般建议能用Schedule Table就不要用Alarm。
如上Alarm所述,当计数器的计数值依次达到各个Alarm设定的计数值时,各个Alarm被触发,但很难保证各个Alarm有特定的时间间隔,且每个Alarm只能激活一个Task或者Event,所以需要多个Alarm来协作实现在同一时刻触发多个Task或者Event,因此Schedule Table应运而生!
Schedule Table会定义一系列终结点(Expiry Point),且每个调度表都有一个以Tick为单位的持续时间(Duration)。每个终结点则是以Tick为单位的距离起始点的偏移量(Offset),在每个终结点可以实现多个Task或者Event的设置。
与报警器类似,一个调度表只能由一个Counter驱动,同时调度表存在以下两种调度方式:
单次执行(Single-Shot): 调度表启动之后 只运行一次,到达调度表终点则终止,即每个终结点只运行一次;
循环执行(Repeating): 调度表启动后可反复执行,到达调度表终点后重头开始执行,则每个终结点会被周期性的执行,一般情况下激活任务采用此模式。
如下图10所示,较为清晰了描述了调度表中Expiry Point与Task,Event激活之间的时序关系。
Schedule Table时序图
注意点:
在AUTOSAR中定义了两类中断服务程序(Interrupt Service Routine)。分别为一类中断(Category I)与二类中断(Category),两者之间的区别定义如下:
在AUTOSAR OS中,中断的优先级始终高于任务的优先级,即最低优先级的中断都可以打断最高优先级的任务,即使该任务不可抢占也不例外。 因此,中断服务子程序的执行时间不宜过长,否则会影响到整个系统的实时性。