AUTOSAR/OSEK OS 与其他常规RTOS的区别
每一个RTOS都将会有其独特的设计之处,例如ucOS,那个8x8的任务优先级就续表,我想必然惊讶了很多人,那是多么巧妙的一个快速查找最高就绪优先级的方法,FreeRTOS和ucOS的该方法比起来,那真是落后好几条大街。好吧,这里不比较ucOS和FreeRTOS,而是比较OSEK OS和FreeRTOS等的区别。
看过AUTOSAR OS文档的人都会知道,因为OSEK OS的设计思想太好了,所以AUTOSAR就直接借过来用了,也就是说AUTOSAR OS是基于OSEK OS的,而后在其上增加了些特性和需求,如调度表(Schedule Table),内存保护(Memory Protection)以及应用(Application)的概念。本文主要讲解OSKE OS和其他OS的区别。
首先,从OS支持的功能上看,常规OS如FreeRTOS等支持任务(Task)/报警器(Alarm or Timer)/事件(Event)/消息队列(Message)/信号量(Semaphore)/互斥所(Mutex),可见常规OS所支持的功能还是很丰富的。再看OSEK OS,其支持任务(Task)/报警器(Alarm)/资源(Resource)/事件(Event),其中资源和常规任务的互斥锁类似,但资源引入的一个机制,设置资源天花板优先级来解决了优先级反转和死锁的问题,可以参见OSEK OS 2.2.3文档8.4.1章节,如下是我的翻译(这年头不会英语真的是没法在程序圈混啊):
优先级反转即意味着一个低优先级的任务有可能会先于高优先级任务执行,而使高优先级任务不能够及时的被响应,而OSEK设置资源天花板优先级来解决此类问题。 如上图所示,任务T4优先级最低,运行中,其获取了信号量S1。之后最高优先级任务T1就绪,抢占了任务T4,同样申请获取信号量S1,获取失败而任务T1重新陷入等待状态。之后任务T4被优先级介于T1和T4之间的任务抢占。任务T1仅当所有低优先级任务执行完毕结束之后,并且信号量S1被释放之后,方可执行。由此可见,在此情况下,任务T2和T3虽然不使用信号量S1,但当T2或者T3执行时却可以延迟高优先级任务T4的响应时间,使高优先级任务不能够被及时的响应,此异常称作优先级反转。
如上图所示,任务T1获取了信号量S1,之后陷入等待状态,等待某个事件的发生。这时低优先级就绪任务T2将获得CPU使用权,开始执行,其将获取信号量S2,之后,任务T1等待的事件发生了,任务T1将重新获得CPU使用权,并尝试获取信号量S2,其将重新陷入等待状态,因为这时信号量S2已经被任务T2获取了。这时任务T2恢复执行,如果其尝试获取信号量S1,这是任务T1也会陷入等待状态,这时任务T1和任务T2都因等待一个已经被对方所获取的信号量而陷入死锁状态。
这里突然想到了曾经和一个朋友在一起吃饭时,他向我讲述了一件事情,说他去面试时,面试官问了他一个问题,在OS不提供死锁避免机制的前提下,在开发应用程序时如何避免死锁,当我听到这个问题时,我也瞬间懵了,很多时候,我们都在研究什么是死锁,开发RTOS时,该提供哪些机制去避免死锁,却真未曾思考过在开发应用程序时,如何去避免死锁的问题。其实问题是很容易解决的,那就是所有任务都按照一定的顺序去获取资源。如上图所示,若果任务T1和任务T2都按照先获取信号量S1再获取信号量S2的顺序执行,那么这个死锁将不复存在。这是一种很好的在应用程序端避免死锁的方法。另外个人猜测,微软提供API WaitForMultipleObjects 就是出于此目的。但是现实的应用需求可能是复杂的,有些时候,应用程序的逻辑复杂度上去了,导致了不能够保证一定按一定顺序去获取资源,那这个时候,就只能够依靠OS来提供机制避免死锁的发生,如ucOS/FreeRTOS的资源等待超时的方法,但此方法却毕竟能力有限,还是依赖应用程序来判断是否超时来决定执行何种操作。但这也不能说ucOS/FreeRTOS不好,更多的是因为ucOS/FreeRTOS不是一个纯静态配置的操作系统,其支持任务/信号量等的动态创建,从而其不能像OSEK OS那样采取设置资源天花板优先级的方法来解决问题,但也折中的提供了改变当前任务优先级的API(如FreeRTOS API vTaskPrioritySet)来实现死锁的避免。
为避免此问题,OSEK OS定义了资源的天花板优先级的概念,其有以下行为:
-
在系统静态生成时,每个资源的天花板优先级是静态指定分配的,天花板优先级必须至少大于等于所有访问该资源或其链接资源任务中的最高优先级,并且天花板优先级必须小于所有不访问该资源且任务优先级大于所有访问该资源任务优先级的任务中的最低优先级;
-
当任务访问该资源,且其当前优先级低于该资源的天花板优先级时,任务须提升优先级至天花板优先级;
-
当任务释放资源时,须重置任务优先级至申请该资源时的优先级。
如上图所示,展示了天花板优先级的原理。任务T0具有最高优先级,任务T4具有最低优先级,任务T1和任务T4都会访问同一个资源,系统展示了将没有优先级反转的发生,任务T1将仅等待资源被任务T4占用的一个较短时间而就会获得优先响应。
以上很多内容纯粹为文档翻译,其实,该天花板优先级反转也有其缺陷,正如文档所述,如上图所示,如果任务T1在任务T4获取资源后未进入就绪状态,那么可明显看到,高优先级任务T2和T3却未能被及时响应,可谓算是另外一种优先级反转,所以问题并未彻底的解决,只是说使用该方法能保证更高优先级任务的优先响应。所以说天花板优先级会导致优先级小于等于天花板优先级任务的响应延时,这延时时间即低优先级任务占用资源的时间。考虑到高优先级任务更重要和一般OSEK OS任务的设计思想即不要过长时间的占用资源,所以这种由天花板优先级导致的优先级反转是可以被接受的。
请自行脑补死锁使如何被避免的,其原理很简单,访问相同多个资源的任务一旦获取其中一个资源,另一个任务将不可能进入运行状态,所以死锁也将不复存在。
好吧,一篇文章,写了2个星期终于算是完结,最近太懒了。