基于OSEK/VDX標準的Trampoline操作系統(tǒng)研究
摘要 介紹了基于OSEK/VDX標準的開源嵌入式實時操作系統(tǒng)Trampoline,詳細分析了該操作系統(tǒng)內(nèi)核調(diào)度、任務管理和中斷管理的實現(xiàn)機制,并指出了Trampoline為實現(xiàn)高可移植性、小內(nèi)存的設(shè)計目標時對0SEK任務管理和中斷管理所作的優(yōu)化。最后,給出了在Linux/x86平臺上使用Trampoline開發(fā)應用程序的方法。
關(guān)鍵詞 OSEK/VDX Trampoline 任務調(diào)度 任務管理 中斷管理
1 OSEK操作系統(tǒng)研究現(xiàn)狀及相關(guān)工作
OSEK/VDX標準產(chǎn)生以后,很多操作系統(tǒng)供應商對其進行研究,并實現(xiàn)了商業(yè)化,例如國外Elektrobit Auto—motive、 Accelerated Techno1ogy、 dSPACE、 ETAS、Metrowerks、Hitex、iSYSTEM、Lauterbach Datentechnik、Vector、WindRiver等公司。這些公司的OSEK操作系統(tǒng)產(chǎn)品都通過了OSEK官方認證,并提供了配套的集成開發(fā)環(huán)境來方便應用程序的開發(fā)。
國內(nèi)依據(jù)0SEK/VDX開發(fā)的操作系統(tǒng)內(nèi)核,大部分參考了μC/OS操作系統(tǒng)內(nèi)核的設(shè)計或者是在它的基礎(chǔ)上修改的,也有在Linux的基礎(chǔ)上修改的。國內(nèi)OSEK操作系統(tǒng)配套的集成開發(fā)環(huán)境很少,目前有浙江大學開發(fā)的SmartIDE、清華大學開發(fā)的清華車用集成開發(fā)環(huán)境等,其他的基本上沒有配套的集成開發(fā)環(huán)境。因此目前國內(nèi)對OSEK標準的研究和應用還處于初級階段。
由于購買商業(yè)化的OSEK需要大量資金,并且很多時候不能獲取源代碼,因此希望有一些開源OSEK操作系統(tǒng)來滿足研究的需要?,F(xiàn)有的OSEK操作系統(tǒng)的開源實現(xiàn),有PICosl8,一個OSEK/VDX OS 2.1r1的部分實現(xiàn)。它專門為PICl8XXX系列微控制器設(shè)計,針對該系列微控制器硬件,特別是在內(nèi)存使用方面作了高度優(yōu)化。但是,它的定制能力很差,并且移植到其他平臺時代碼修改量很大。另外還有openOSEK項目,但是該項目一直沒有開發(fā)出正式發(fā)布的版本。
Trampoline主要是由法國通信研究所(IRCCyN)的實時系統(tǒng)組負責開發(fā)的。它的源代碼是開放的,能夠兼容OSEK/VDX OS 2.2.3標準(當前最新版本為1.1)。它目前還沒有通過OSEK/VDX的官方認證,因此只能說它兼容OSEK標準,而不能說它是通過OSEK認證的操作系統(tǒng)。Trampoline目前能夠在4個平臺上運行,分別是POSIX(包括Linux、Unix、Mac OS等)系列操作系統(tǒng)平臺、Infineon C166平臺、Freescale S12x平臺、Darwin/PowerPC平臺,其中在POSIX系列操作系統(tǒng)上運行時需要libpcl庫的支持。因此,即使沒有微控制器,也可以在常見的Linux/x86平臺上使用Trampoline。
要對整個OSEK/VDX標準進行研究,對OSEK操作系統(tǒng)的研究是基礎(chǔ)。只有有了一個可以使用的OSEK操作系統(tǒng),才能在它的基礎(chǔ)上進行COM、NM及OIL標準的研究,才能進行OSEK操作系統(tǒng)應用程序開發(fā)、汽車電子集成開發(fā)環(huán)境的開發(fā)等方面的研究。Trampoline能夠在Linux平臺上運行,并且有一個可用的GOIL OIL文件解析器,可以作為進行OSEK/VDX標準研究的基礎(chǔ)。
2 OSEK OS及Trampoline分析
OSEK操作系統(tǒng)是一種單處理器操作系統(tǒng),主要用于汽車電子的分布電子控制單元ECU(Electronic ControlUnit)上。
OSEK操作系統(tǒng)對不同版本OSEK操作系統(tǒng)提供的應用程序接口進行了標準化,這樣,為一個OSEK操作系統(tǒng)設(shè)計的應用程序不用修改就可以移植到其他OSEK操作系統(tǒng)上運行。
為了使OSEK操作系統(tǒng)能夠在有不同計算能力(不同CPU、不同存儲容量)的ECU上運行,OSEK定義了4個符合類,分別是BCCl、ECCl、BCC2、ECC2。每一個符合類包括一組操作系統(tǒng)特性,代表一類應用程序的需求,也包含了這些操作系統(tǒng)特性運行所需要的硬件需求。使用符合類的概念既方便用戶根據(jù)自己的需求及自己的硬件條件來選擇符合自己需要的操作系統(tǒng)特性集合,也使得操作系統(tǒng)供應商可以先提供一部分操作系統(tǒng),也就是先提供對部分符合類的支持,然后再增加更多操作系統(tǒng)特性,支持其他符合類,從而方便了操作系統(tǒng)的開發(fā)。
OSEK操作系統(tǒng)是靜態(tài)配置的,而不是動態(tài)生成的,用戶在系統(tǒng)生成階段能夠使用OIL語言對系統(tǒng)進行配置,指定系統(tǒng)里使用多少個任務、使用哪些資源、需要調(diào)用哪些系統(tǒng)服務等。通過這種方式,用戶可以選擇需要的部分,裁剪掉不需要的,以減少不必要的系統(tǒng)資源。另外,由于系統(tǒng)是靜態(tài)生成的,既減少了動態(tài)生成系統(tǒng)對象的開銷,減少系統(tǒng)內(nèi)存的使用,又可以使系統(tǒng)運行時的行為可預知,提高系統(tǒng)的可靠性和確定性。
由于OSEK操作系統(tǒng)是靜態(tài)生成的,系統(tǒng)運行時的很多信息在系統(tǒng)生成階段就可以確定,于是它提供的任務間同步和通信方法比其他常用的嵌入式實時操作系統(tǒng)要少。它用OSEK PCP(Priority Ceiling Protoco1)協(xié)議來同步資源的并發(fā)訪問,從而提供了任務與ISR之間及ISR與ISR之間共享資源的機制。另外,OSEK操作系統(tǒng)還提供了完善的錯誤處理機制,提高了系統(tǒng)的可靠性和容錯能力。[!--empirenews.page--]
Trampoline完全支持OSEK標準要求,實現(xiàn)了OSEK操作系統(tǒng)統(tǒng)一的API接口,支持靜態(tài)配置,支持4個符合類,支持OSEK PCP協(xié)議。另外,Trampoline的設(shè)計還考慮到兩個方面——高可移植性和減少內(nèi)存使用量。
為了達到高可移植性,Trampoline設(shè)計了一個硬件抽象層來隔離底層的硬件差異,把平臺有關(guān)的代碼與平臺無關(guān)的代碼進行隔離。把Trampoline從一個目標平臺移植到另一個目標平臺,僅需要把與目標平臺有關(guān)的那部分代碼改寫一下就可以了,硬件抽象層之上的那部分不用修改,這大大減少了操作系統(tǒng)移植的工作量。在Trampoline代碼的組織中,不同目標平臺代碼放在不同的文件中,分離得很清楚。與目標平臺有關(guān)的代碼,僅僅是任務上下文切換、操作系統(tǒng)初始化及一些與硬件相關(guān)的函數(shù)(中斷使能、睡眠模式等)代碼。這部分代碼量減到了最少。由于車載嵌入式系統(tǒng)中的微控制器RAM容量很小,一般從幾百字節(jié)到幾K字節(jié),而增加RAM容量會增加產(chǎn)品的成本,在產(chǎn)品批量生產(chǎn)時往往會難以接受。Trampo—line在設(shè)計時盡量減少內(nèi)存的使用,并優(yōu)化了任務管理和中斷管理的數(shù)據(jù)結(jié)構(gòu),把一部分不變的內(nèi)容放到ROM中,以減少RAM的使用要求。
下面著重分析Trampoline最核心的調(diào)度機制、任務管理、中斷管理的設(shè)計與實現(xiàn)。
2.1 調(diào)度機制
Trampoline使用靜態(tài)優(yōu)先級調(diào)度算法。在系統(tǒng)生成階段,用戶為每一個任務分配一個優(yōu)先級。在不同的符合類下,優(yōu)先級與任務的對應關(guān)系不同。在BCCl和ECCl符合類下,一個優(yōu)先級僅對應一個任務,不同的任務有不同的優(yōu)先級,任務之間不能共享優(yōu)先級;而在BCC2和ECC2符合類下,一個優(yōu)先級可以對應多個任務,不同的任務可以共享同一個優(yōu)先級。任務有4種狀態(tài):就緒狀態(tài)、等待狀態(tài)、掛起狀態(tài)(僅ECCl和ECC2符合類下有)及運行狀態(tài)。
由于使用處于等待或者掛起狀態(tài)的任務時直接給出了該任務結(jié)構(gòu),因此Trampoline沒有使用數(shù)據(jù)結(jié)構(gòu)來管理等待狀態(tài)和掛起狀態(tài)的任務;而對于就緒狀態(tài)的任務,在不同的符合類下,Trampoline采用了兩種不同的數(shù)據(jù)結(jié)構(gòu)來管理。由于在BCCl和ECCl符合類下不同的任務有不同的優(yōu)先級,Trampoline使用一個簡單的鏈表,按照任務的優(yōu)先級由高到低把就緒態(tài)任務描述符給連接起來;而在BCC2和ECC2符合類下,幾個任務可以共享一個優(yōu)先級,Trampoline使用了一個任務子集鏈表數(shù)據(jù)結(jié)構(gòu)來組織就緒任務。共享一個優(yōu)先級的任務組成了一個任務子集,它們也組成了一個鏈表。然后把不同子集的鏈表表頭按優(yōu)先級由高到低鏈接起來,組成了所有就緒任務的鏈表,如圖l所示。由于按照優(yōu)先級由高到低的順序來組織任務子集鏈表,因此最高優(yōu)先級的任務總是在鏈表頭部,這樣會使調(diào)度器能快速選取到最高優(yōu)先級的任務,但也會導致低優(yōu)先級任務選取得很慢。
Trampoline使用一個tpl_running_task指針指向當前正在運行的任務。調(diào)度器管理著就緒任務的集合,當重新調(diào)度發(fā)生時,從就緒任務集合中選取一個最高優(yōu)先級的任務來執(zhí)行,并把它從就緒任務集合里刪除。然后,tpl_running_task指針指向該任務,并把任務的狀態(tài)由就緒態(tài)改為運行態(tài)。該任務將一直處在運行狀態(tài),直到運行結(jié)束或一個系統(tǒng)服務阻塞了它的執(zhí)行,或被一個更高優(yōu)先級任務搶占。另外,一個任務可以是不可搶占的。在這種情況下,它將一直占有CPU,直到運行結(jié)束(即使有一個更高優(yōu)先級就緒任務在等待)。Trampoline也支持使用任務組的結(jié)構(gòu)來實現(xiàn)混合調(diào)度。在這種調(diào)度模式下,把所有就緒任務分成不同的任務組,同一個任務組里的任務之間是不可搶占的,但它可以被這個組外的更高優(yōu)先級任務搶占。
2.2 任務管理
Trampoline使用任務描述符結(jié)構(gòu)(struct tpl_task)來管理任務的信息,其中包括系統(tǒng)運行時不斷變化的信息,如任務狀態(tài)、任務優(yōu)先級、任務的激活次數(shù)、任務的資源、
任務的事件等;還包括系統(tǒng)運行時不變的信息,如任務的上下文、任務的堆棧、任務代碼段入口地址、任務ID、任務基礎(chǔ)優(yōu)先級、最大激活次數(shù)和類型等信息。為了減少內(nèi)存的使用,Trampoline任務描述符結(jié)構(gòu)被分成圖2所示的兩個部分:第一部分是系統(tǒng)運行時不斷變化的數(shù)據(jù),保存在tpl_exec_common結(jié)構(gòu)里,它必須常駐RAM中;另一部分是在系統(tǒng)運行時不變的部分,保存在tpl_exec_static結(jié)構(gòu)里。在tpl_exec_common結(jié)構(gòu)里設(shè)置了一個指針static_desc,指向任務的tpl_exec_static結(jié)構(gòu)。由于tpl_exec_static里存放的信息在系統(tǒng)運行時是不變的,因此可以把這部分放到ROM里,以節(jié)省RAM的使用。在tpl_exec_static結(jié)構(gòu)里有兩部分是體系結(jié)構(gòu)相關(guān)的,即上下文結(jié)構(gòu)context和堆棧結(jié)構(gòu)stack,它們使用指向一個或多個RAM區(qū)域的指針來保存任務執(zhí)行的上下文和堆棧信息。這種設(shè)計使得不同的任務之間可以通過共享指向上下文或堆棧結(jié)構(gòu)的指針就能共享上下文和堆棧,從而可以減少任務上下文和堆棧所占用的存儲空間。另外,Trampoline上下文結(jié)構(gòu)的設(shè)計可以使用盡可能少的RAM。例如,如果目標平臺處理器沒有FPU(浮點處理器),Trampoline上下文結(jié)構(gòu)有兩個指針,第一個指向整數(shù)上下文的RAM區(qū)域,第二個指向浮點上下文RAM區(qū)域,這些RAM區(qū)域都是用來保存任務運行時要使用的整數(shù)寄存器或浮點寄存器的。然而,并不是每個任務都需要使用浮點寄存器,如果任務沒有使用FPU,第二個指針將會設(shè)為空,以避免分配浮點寄存器所占用的RAM空間。任務上下文和堆棧結(jié)構(gòu)都屬于與體系結(jié)構(gòu)有關(guān)的代碼,內(nèi)核不直接同這部分打交道,而是通過硬件抽象層來使用它們。這樣,使得與體系結(jié)構(gòu)相關(guān)的代碼與無關(guān)的代碼隔離起來,從而便于把它移植到其他平臺。[!--empirenews.page--]
2.3 中斷管理
在OSEK操作系統(tǒng)中,ISR(Interrupt Service Routine)分成了兩類,即ISRl和ISR2。ISRl不使用操作系統(tǒng)服務,也不能調(diào)用其他的用戶定義函數(shù)。該類中斷服務例程執(zhí)行完了以后直接執(zhí)行中斷發(fā)生位置后的下一條指令,因此ISRl對任務管理沒有影響,運行時消耗的資源也比較少。ISR2是可以調(diào)用其他用戶定義的函數(shù)或使用部分OSEK服務的中斷例程,OSEK操作系統(tǒng)專門為它準備了一個堆棧Frame,用作調(diào)用其他函數(shù)的執(zhí)行環(huán)境。在系統(tǒng)生成階段,由用戶指定ISR2要調(diào)用的用戶定義函數(shù)或系統(tǒng)調(diào)用。ISR2能夠和任務之間共享資源,而這可能會造成死鎖:當ISR2啟動后試圖獲得一個已經(jīng)被一個任務占用的資源時,該任務也在等待中斷完成,因此ISR2和任務之間共享資源時需要使用同步機制。OSEK操作系統(tǒng)提供了用于資源訪問的GetResource和ReleaseResouree系統(tǒng)調(diào)用,任務和ISR2之間可以使用它們來共享資源,但是這種方法需要關(guān)閉訪問資源的中斷,可能使中斷長時間關(guān)閉,降低了操作系統(tǒng)的實時響應能力。另一種任務和ISR2之間共享資源的方法是OSEK標準所建議的方法,也就是使用OSEK PCP協(xié)議。使用這種方法時,當一個任務要獲取同ISR2共享的資源時,會把它的優(yōu)先級提升到比ISR2更高的優(yōu)先級,當任務執(zhí)行完成之后,再把優(yōu)先級恢復到原來的優(yōu)先級。這時ISR2更像任務,但是比普通任務有更高的優(yōu)先級。
Trampoline實現(xiàn)了一種延遲的ISRl和ISR2,從而使操作系統(tǒng)內(nèi)核更小。任務和ISR的描述符都繼承自一個tpl_exec_common結(jié)構(gòu),如圖2所示。任務描述符在tpl_exec_common結(jié)構(gòu)里增加了事件管理的數(shù)據(jù)成員,也就是evl_set和evt_wait數(shù)據(jù)成員;而ISR描述符在tpl_exec_common結(jié)構(gòu)里增加了一個指向附加數(shù)據(jù)的指針,也就是static_isr_desc數(shù)據(jù)成員,static_isr_desc指向的內(nèi)容可以放到ROM中,以減少RAM的使用。一個ISR對應著一個中斷向量。當一個中斷觸發(fā)時,Trampoline激活對應的ISR中斷服務例程并且返回。如果是ISRl,執(zhí)行完了以后將執(zhí)行觸發(fā)中斷位置后面的代碼;如果是ISR2,ISR2將運行預先定義的用戶定義函數(shù)或者系統(tǒng)服務,然后像普通任務一樣由調(diào)度器根據(jù)任務級的調(diào)度策略來調(diào)度執(zhí)行。
另外,Trampoline為ISR增加了一個抽象層。這樣,一方面幾個硬件中斷可以共享相同的中斷向量偏移,另一方面對應到一個中斷向量偏移的,有一個ISR的集合,而不是一個ISR。當一個硬件中斷觸發(fā)時,為了找到一個與該硬件中斷匹配的ISR,每組共享中斷偏移的ISR都必須提供一個函數(shù)來測試它對應的設(shè)備中斷標志是否為真。如果函數(shù)返回TRUE,該ISR將被激活。Trampoline設(shè)計了一種GIH(General Interrupt Handler)函數(shù)來完成這種測試工作。
而這樣做有兩個問題。第一,由于ISR2的后期執(zhí)行是在任務態(tài)運行,這時如果有一個硬件中斷觸發(fā),就會由GIH來確定一個ISR來執(zhí)行,從而打斷了原來的ISR2。即使后來觸發(fā)的ISR的優(yōu)先級比原來ISR2的優(yōu)先級低,這種情況也能發(fā)生。這就造成了一個低優(yōu)先級的硬件中斷搶占了高優(yōu)先級的中斷,而這種情況是不應該發(fā)生的,因此是一個很大的問題。第二,根據(jù)OSEK操作系統(tǒng)標準,當ISR運行時,不能進行重新調(diào)度。在Trampoline中,ISR2作為高優(yōu)先級的普通任務進行調(diào)度,當一個高優(yōu)先級ISR2到來時,任務調(diào)度器會重新調(diào)度一次,從而打斷了原來的ISR2的執(zhí)行。另外,在OSEK操作系統(tǒng)標準中,重新調(diào)度是在任務之間的重新調(diào)度;而在Trampoline中,只要有一個ISR2在運行,重新調(diào)度只能在有比普通任務更高優(yōu)先級的ISR2之間進行。當最后運行的ISR2結(jié)束時,CPU的重新調(diào)度才給了有最高優(yōu)先級的任務,因此,Trampoline的中斷管理部分的實現(xiàn)還有待改進。
3 在Linor/x86上開發(fā)TramooIine應用程序
Trampoline目前可以在四種目標平臺上使用:帶有Keil編譯器的Infineon C167、Darwin/PowerPC、FreesealeS12x和POSIX系列操作系統(tǒng)平臺。前三種平臺的硬件不常見,如果沒有就不能運行;而POSIX系列的Linux/x86平臺則很容易得到。下面以Linux/x86平臺為例,說明開發(fā)一個Trampoline應用程序的步驟和方法:
①生成應用程序的OIL配置文件。OSEK/VDX 0S是一個靜態(tài)操作系統(tǒng),系統(tǒng)對象需要在系統(tǒng)生成時定義。OIL是書寫這種定義的標準語言。它可以定義所有的應用程序使用的各種對象(任務、中斷、警報、計數(shù)器、資源、事件等)。OIL配置文件可以手工編寫,也可以使用圖形化開發(fā)配置工具來生成。目前Trampoline沒有圖形化配置工具,只能手工編寫OIL配置文件。
②使用OIL文件解析器GOIL將應用程序的OIL文件轉(zhuǎn)化為一個.c文件和.h文件,其主要功能是進行與應用程序相關(guān)的各種系統(tǒng)對象參數(shù)的定義、初始化等工作。
③使用GCC工具鏈將②生成的文件和Trampoline操作系統(tǒng)內(nèi)核文件及l(fā)ibpcl庫文件、VIPER虛擬處理器文件等進行編譯和鏈接,生成一個Linux平臺的可執(zhí)行文件,也就是最終的應用程序可執(zhí)行文件。