作者 | 奮斗的農民工
來源 | ADAS與ECU之吾見
前言
-
為什么汽車電子ECU需要使用OS呢,它的必要性在哪里?
-
-
-
今天,我們來一起探索并回答這些問題。為了便于大家理解,以下是本文的主題大綱:
正文
為啥要用OS?
我們知道傳統所說的“裸機編程”就是不帶操作系統的編程,在系統需求相對比較簡單的情況下使用裸機編程可以滿足要求。
但是隨著系統需求越來越復雜,此時就需要用到模塊化設計方法以及多任務編程思想,否則后期軟件升級維護成本將會急劇增加。
雖然我們可以采用傳統編程方式(如計數器與狀態機)來實現簡單多個任務的調度,但是當涉及到多個任務之間的狀態切換,優先級,現場保護,執行時間控制等方面就顯得極為吃力,開發效率低下且極容易出錯。
此時迫切需要一種機制來替我們完成各個任務之間的調度功能,使得開發人員能夠更關注于應用軟件的開發,提高軟件開發效率。
為此
OS(Operation System)
便應運而生!實際上,OS主要是為我們解決了以下幾個基本問題:
-
-
-
設定各任務的優先級,保證高優先級任務能夠及時執行;
-
-
其中調度功能則是OS的核心組件,主要功能就是負責任務的切換。在一個單核系統中,多任務只能并發執行,通過
時間片輪轉法
來切換任務。
通過時鐘中斷或者軟中斷的方式來觸發一次任務的切換,從而打斷當前執行任務,調度器搶奪CPU控制器,來進行任務調度并切換至新任務開始執行,如下圖1所示:
對于傳統汽車電子開發領域,早期使用的OS則是
OSEK OS,
其中OSEK是德文的縮寫,譯為
汽車電子開放系統及接口
。
OSEK OS是一個為滿足汽車電子可靠性、實時性、成本敏感性等需求而打造的
實時單核操作系統(RTAOS)
。
該實時單核操作系統具備以下基本特性以及基本系統服務,如下圖2所示:
AUTOSAR OS與OSEK OS聯系
首先,
AUTOSAR OS是基于OSEK OS繼承發展而來,
所以上述的OSEK OS的基本特點在AUTOSAR OS都能夠得到滿足,所以AUTOSAR OS是向后兼容的,也就意味著在OSEK OS上能夠運行的應用程序同樣也可以在AUTOSAR OS上運行。
除此之外,AUTOSAR OS也存在自身的一些獨特的基本特點,下面將從該OS的基本屬性與系統基本服務兩個方面展開:
AUTOSAR OS在OSEK OS的基礎上,除了上述的基本特點之外,仍需要確保具備以下幾點十分重要的屬性:
AUTOSAR OS繼承OSEK OS,在OSEK OS的基礎上又特別明確了AUTOSAR OS至少需要提供的系統服務如下:
基于優先級的調度;
及時的中斷處理的能力;
中斷優先級必定高于task;
通過StartOS()與StartOSHook()來創建啟動接口;
通過ShutdownOS()與ShutdownOSHook()來創建關機接口;
能夠在OSEK OS中跑的APP自然也能夠在AUTOSAR OS運行,但同時Autosar os也同時限制了OSEK OS的一些基本使用;
AUTOSAR OS基本對象
AUTOSAR OS總共包含以下5大基本對象:Counter,Alarm,Schedule Table,Task,ISRs。
這5個基本對象必須歸屬于一個OS Application,可以簡單理解為
OS Application是上述5大基本對象的容器。
而歸屬于同一OS Application的基本對象則可以互相訪問,來自其他OS Application的基本對象則需要通過配置來限制性訪問。
這5大基本對象,OS Application,Core這三者存在著一定的關系,為了更好的理解它們之間彼此的關系,如下圖4就較為清晰地描述了者三者之間的關系。
如上圖所示,以單核為例,
每一個Core可包含1~N個OS Application,而每一個OS Application可包含0~N個基本對象。
每個基本對象必須從屬于某個OS Application,否則會出現錯誤。同時OS Application可分為Trusted與Not Trusted這兩種類型。
Trusted 與Not Trusted 的OS Application在運行過程中可以配置相應的監控與保護機制。
從屬于Not Trusted OS Application的OS基本對象對存儲器和API的訪問將受到限制。
通常會將一些基礎軟件的模式管理主函數映射到
Not Trusted OS Application
中的任務,如
EcuM_Mainfunction,BswM_Mainfunction, Can_Mainfunction_Mode()
等周期性狀態查詢函數,當然前提這些軟件模塊的安全級別為QM。
接下來,將針對這5大基本對象分別展開講述各個對象的基本特點與用途,以便大家在對OS配置的過程中有一個更為清晰的認識。
AUTOSAR OS中存在兩種任務:基本任務(Basic Task)和擴展任務(Extended Task)。基本任務則存在以下三種狀態:
-
運行狀態(Running):
處于運行狀態的任務可能被高優先級任務或者中斷搶占從而進入就緒狀態,且同一Core中任何時刻只會存在一個任務處于運行狀態,任務運行結束后則將自己掛起進入阻塞狀態;
-
就緒狀態(Ready):
處于就緒狀態的任務由調度器決定是否啟動進入運行狀態,且該狀態時任務切換至運行狀態的前提;
-
阻塞狀態(Suspend):
處于阻塞狀態的任務是被動的,可以由API函數或Alarm激活進入就緒狀態;
擴展任務與之相比,則多了一個等待狀態(Waiting),解釋如下:
-
等待狀態(Waiting):
當任務的運行需要等待某一或某些事件被置位時,任務進入就緒狀態。
基本任務的代碼示例如下:
#include “OS.h”
TASK(BasicTask)
{
...
/*User Code*/
...
TerminateTask();
}
擴展任務的代碼示例如下
#include “OS.h”
TASK(ExtendedTask)
{
for(; ;)
{
WaitEvent(Event1);
/*Perform some actions in specific condition*/
ClearEvent(Event1);
}
}
基本任務與擴展任務的狀態機切換如下圖5所示:
如上圖所示,基本任務沒有等待狀態,所以只能在任務啟動與終結時進行同步,基本任務的優點就是占用較小的任務與執行時間。
擴展任務則包含多個同步點,沒有同步請求的麻煩,當進一步的條件無法滿足時,任務則會切換至等待狀態,其缺點也很明顯,會占用較多的內存和執行時間。
Task的符合類(Conformance Class,簡稱CC)
AUTOSAR OS根據不同的軟硬件需求,根據每個優先級可能具備的任務個數以及需要的是基本任務還是擴展任務等來定義了四種符合類分別為
BCC1,BCC2,ECC1以及ECC2,
各種符合類及屬性其如下圖6所示:
由上表可知,基本符合類BCC1與BCC2僅支持基本任務,擴展符合類ECC1與ECC2基本任務與擴展任務均支持。
BCC1與ECC1不支持多次任務激活請求且每個優先級只能有一個任務;BCC2與ECC2既支持多次任務激活請求,同時也支持每個優先級可以有多個任務。各種符合類之間的兼容關系如下圖7所示:
AUTOSAR OS是基于優先級進行任務調度,所以每個任務必定有一個優先級,而每個任務都是根據其自身特點來定義一個優先級且需要配置其可搶占屬性。
可搶占屬性可分為不可搶占與全搶占,這里所說的搶占指的是內核搶占。AUTOSAR OS可根據各個任務的可搶占屬性配置,來提供不同的調度策略,調度策略可分為以下三種:
-
-
-
混合搶占式:
OS部分任務是可搶占類型,部分任務是不可搶占類型;
1.對于完全搶占式任務調度策略而言,當前運行的任務可在任何時刻被高優先級任務打斷而被迫釋放處理器控制權,具備最高優先級的任務從就緒狀態轉入運行狀態,而當前任務被搶占從而進入就緒狀態,同時保留現場環境,待下次運行時恢復。
如下圖8所示為完全搶占式任務調度策略,TaskA為擴展任務,TaskB與TaskC為基本任務,優先級TaskA > TaskB > TaskC。
當前TaskC處于運行狀態,當激活TaskB進入到就緒狀態時,由于TaskB優先級高于TaskC,所以TaskC被迫釋放處理器控制權,調度器開始調度TaskB從就緒狀態變為運行狀態,直到TaskB運行完成之后,在調度TaskC繼續運行。
當前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,也就意味著在重要代碼執行之前,應采用資源保護機制,以免被高優先級的任務打斷。
2. 若采用非搶占式調度策略,那么當前運行狀態的任務在任何時刻都不會其他高優先級任務所搶占,任務的切換只會發生在任務完成時。
非搶占式調度策略的問題在于任務執行時間不確定,系統調度實時性較差。如下圖9所示為非搶占式調度策略,可見即使高優先級任務 TaskB被激活切換至就緒狀態,也必須等到TaskC執行結束之后才能夠被調度。
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的激活狀況來減少無意義的時鐘中斷;
如下圖10所示,則較為清晰的表現了Counter,Schedule Table以及Alarm三者之間的關系。
圖10 OS 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):
調度表啟動后可反復執行,到達調度表終點后重頭開始執行,則每個終結點會被周期性的執行,一般情況下激活任務采用此模式。
如下圖11所示,較為清晰了描述了調度表中Expiry Point與Task,Event激活之間的時序關系。
-
每一個終結點必須配置至少一個Task或者Event;
-
每一個調度表至少存在一個終結點(Expiry Point);
-
在每一個Expiry Point優先激活Task,隨后設置Event;
在AUTOSAR中定義了兩類中斷服務程序(Interrupt Service Routine)。分別為
一類中斷(Category I)與二類中斷(Category),兩者之間的區別定義如下:
-
Category I:
此類中斷服務程序不能夠使用OS提供的系統服務,當中斷執行完成之后則會重新跳轉至產生中斷的地方繼續執行,不會影響到任務的執行,因此占用系統資源較少。
-
Category II
:該類中斷則可以調用OS系統服務,如激活任務或者設置事件等。
在AUTOSAR OS中,
中斷的優先級始終高于任務的優先級,即最低優先級的中斷都可以打斷最高優先級的任務,即使該任務不可搶占也不例外。
因此,中斷服務子程序的執行時間不宜過長,否則會影響到整個系統的實時性。
Resouce作為OS調度過程中一個十分重要的對象,Resource管理就顯得尤為重要。
資源管理就是為了協調具有不同優先級的多個任務或者中斷對共享內存(如內存或者硬件等)的并發訪問。
不過幸運的是AUTOSAR OS采用上述的優先級天花板模式來避免任務優先級反轉以及死鎖問題的發生,即資源的上限優先級必須高于所有該資源的任務以及中斷的優先級,但是應低于不訪問該資源的任務的最低優先級。
其中為了保護共享資源而提出的鎖機制-自旋鎖(Spin Lock)。該自旋鎖一般用于多核操作系統解決資源互斥的問題。
當內核控制必須訪問共享數據結構或進入臨界區時,如果自旋鎖已經被別的執行單元保持,調用者就一直循環在那里看是否該自旋鎖的保持者已經釋放了該鎖,從而達到某共享資源的互斥作用。
常用函數接口
為了便于大家日常軟件調試,我將常見的OS相關API函數接口及其相應功能表述如下圖12所示:
由于內容較多,篇幅有限,
為
防止給大家造成視覺疲勞,有關多核啟動與關閉、核間通信、內存與時間保護等精彩內容請聽下回分解,敬請諸君多多關注!