丁如藝,張 激,李嘉偉
(中國電子科技集團公司第32 研究所,上海 201808)
隨著嵌入式計算機的飛速發(fā)展與其技術發(fā)展的網絡化[1,2],一些領域對嵌入式操作系統(tǒng)的可靠性、可移植性、開發(fā)效率以及功耗等方面提出了更高的要求[3].
在開發(fā)大規(guī)模復雜系統(tǒng)時,由于不同編程語言和開發(fā)平臺間存在的差異,所以需要開發(fā)人員針對操作系統(tǒng)的特性對應用程序的實現(xiàn)代碼進行相應的修改,這樣不僅增加了他們的工作量,也使得嵌入式產品的研發(fā)周期變得更長.在激烈的市場競爭中,有效地進行資源復才能對用戶的需求做出迅速的響應,高效的滿足其需求.而這種資源復用可以通過接口的標準化或者提高代碼的可移植性來實現(xiàn).
本文對Linux 系統(tǒng)及國產嵌入式實時操作系統(tǒng)“銳華”進行研究,提出了一種通用性較強的平臺抽象層(Platform Abstraction Layer,PAL).平臺抽象層針對不同操作系統(tǒng)和硬件平臺的應用程序開發(fā)接口(Application Programming Interface,API)進行抽象,為用戶提供標準化接口進行嵌入式開發(fā).與現(xiàn)有的抽象層設計方案相比,平臺抽象層不但可以應用于不同嵌入式操作系統(tǒng),同時還可以提高操作系統(tǒng)的通用性和應用程序的可移植性.
嵌入式系統(tǒng)是以應用為中心,以計算機技術為基礎,并且軟硬件可裁剪,適用于應用系統(tǒng)對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機[4].如圖1 所示,在傳統(tǒng)的嵌入式系統(tǒng)組成結構中,嵌入式系統(tǒng)包含硬件系統(tǒng)與軟件系統(tǒng)兩部分.硬件系統(tǒng)包括處理器/微處理器、存儲器、I/O 接口、外設器件;軟件系統(tǒng)主要包括嵌入式操作系統(tǒng)、嵌入式應用程序以及應用程序開發(fā)接口.
圖1 嵌入式系統(tǒng)結構圖
實時嵌入式操作系統(tǒng)(Real-Time embedded Operating Systems,RTOS)是一種實時、支持嵌入式系統(tǒng)應用的操作系統(tǒng)軟件,在嵌入式軟件系統(tǒng)中距離硬件最近,與硬件聯(lián)系最為緊密[5].
本文所選取的嵌入式實時操作系統(tǒng)——“銳華”是中國電子科技集團公司第32 研究所自主研制的操作系統(tǒng).該操作系統(tǒng)的內核采用了“十二五”核高基成果——ReWorks.ReWorks 內核可搶占、中斷可嵌套,并且具備高效的中斷管理機制和任務調度、上下文切換算法,具有強實時性.其采用微內核的體系架構和面向對象的設計方法,具有良好的可裁剪性.ReWorks 的接口設計符合POSIX 標準[6],具有較強的可移植性.此外,ReWorks 作為一款自主可控的操作系統(tǒng),還具有可持續(xù)性特點[7].
Windows NT 是一個被廣泛應用的搶占式多任務操作系統(tǒng).為了提高其穩(wěn)定性與兼容性,微軟公司首次提出了硬件抽象層(Hardware Abstract Layer,HAL)的概念,將大部分與硬件相關的操作放在內核和硬件抽象層中,由內核與硬件抽象層負責完成與硬件操作有關的細節(jié).
硬件抽象層以動態(tài)鏈接庫的形式(HAL.DLL)提供面向平臺的函數(shù).這些函數(shù)將Windows NT 操作系統(tǒng)與其所依賴的基本硬件進行了分離,不需要對設備驅動程序做任何修改就可以支持同類處理機不同平臺中的相同設備[9].
由于硬件抽象層的優(yōu)化是針對PC 的,所以無法適用于嵌入式應用開發(fā)環(huán)境.
實時硬件抽象層(Real Time Hardware Abstract Layer,RTHAL)是Linux 操作系統(tǒng)和底層硬件之間的一個中間層.RTHAL 對硬件完全控制,為Linux 屏蔽了硬件細節(jié)并禁止其對硬件直接操作,中斷管理、任務管理、時鐘管理等相關操作均由實時硬件抽象層完成.RTHAL 為硬件提供接口,Linux 和硬實時操作系統(tǒng)運行在其之上,有效的避免了操作系統(tǒng)對Linux 內核進行大量的修改,減少對標準Linux 內核可能帶來的負面影響[11].
由于實時硬件抽象層是面向Linux 系統(tǒng)的,其結構、功能以及定義的接口都與Linux 系統(tǒng)緊密相關,所以無法為其他嵌入式系統(tǒng)所用.
文獻[12]利用C++的虛函數(shù)機制,提出了操作系統(tǒng)抽象層(Operating System Abstraction Layer,OSAL)的概念.OSAL 封裝具體操作系統(tǒng)實體為應用提供所需的各種服務,使開發(fā)的應用與操作系統(tǒng)完全無關,從而使應用的兼容性更強.
由于文獻[12]使用的是面向對象的語言C++,執(zhí)行過程中會引入大量臨時對象,導致性能方面損失較大.同時實踐證明,僅對操作系統(tǒng)進行抽象是不夠的,還需考慮硬件平臺的特殊性,所以該方案仍有改進空間.
PAL 由操作系統(tǒng)抽象、硬件平臺抽象和設備驅動抽象3 個部分構成,如圖2 所示,對操作系統(tǒng)和硬件平臺進行了封裝.這3 個部分可以形象的分為兩層:上層為應用程序提供基于POSIX 標準的標準化接口,這些接口不隨宿主平臺的改變而改變,使得開發(fā)的嵌入式應用不再拘泥于某一平臺;下層是這些接口在操作系統(tǒng)與硬件平臺上的具體實現(xiàn).
圖2 PAL 內部結構
加入PAL 后,軟件體系結構在操作系統(tǒng)與應用程序之間多出一個獨立接口層,該接口層起到了銜接不同操作系統(tǒng)、硬件平臺與應用程序的作用,如圖3.
本小節(jié)對平臺抽象層中提供操作系統(tǒng)基礎服務的接口進行了簡單的描述,具體如下:
任務接口:任務接口用于提供任務的注冊、創(chuàng)建、刪除、查詢以及延遲服務.
信號量接口:信號量接口與經典操作系統(tǒng)中的設計思路一致,主要提供二進制信號量、計數(shù)信號量、互斥信號量的創(chuàng)建、刪除、釋放、鎖操作、等待以及查詢服務.
消息隊列接口:消息隊列接口用于提供隊列的創(chuàng)建、刪除、消息獲取、消息輸入、查詢服務.
定時器接口:定時器接口用于提供定時器的初始化、創(chuàng)建、設置、查詢、刪除服務.
文件系統(tǒng)接口:文件系統(tǒng)接口除了用于提供文件和目錄的創(chuàng)建、刪除、打開、關閉服務以外,還為基于PAL 開發(fā)的應用程序提供了從文件中讀取數(shù)據、向文件中寫入數(shù)據和在文件中查詢數(shù)據的服務.
中斷/異常處理接口:與傳統(tǒng)的中斷機制一致,該模塊接口用于提供中斷和異常的使能、關閉、關聯(lián)以及鎖操作服務.
除了上述接口,PAL 還包括用于應用程序初始化、打印輸出、等待的空閑任務接口等.
平臺抽象層中部分設計的接口的具體實現(xiàn)如表1所示,即PAL 上層提供給應用程序的標準化接口.
圖3 包含PAL 的體系結構
表1 PAL 部分接口及實現(xiàn)
在PAL 的設計中,以宏的方式實現(xiàn)平臺抽象層對不同操作系統(tǒng)和硬件平臺的支持,來滿足一些平臺的特殊需求.例如,對于基于glibc 的Linux 系統(tǒng),定義宏“_XOPEN_SOURCE=600”來啟用X/Open 6 標準.因為glibc 支持多個標準[13],所以需要添加額外的宏定義以確定編譯時采用的標準;對于不同的操作系統(tǒng),定義宏“OS =”進行系統(tǒng)選擇,這種方法的好處在于隨著需要支持的操作系統(tǒng)增多,可以通過直接修改宏的方式增加選項,避免重復的工作.類似的,也可以通過定義宏“BSP =”來選擇不同硬件平臺.
通過使用宏并采用條件編譯的方法,可以實現(xiàn)基于程序的透明性.
由于自定義標識符可能會與C 庫提供的其他標識符重疊,或與操作系統(tǒng)中的定義重疊,所以在設計時為自定義標識符添加前綴,避免命名空間帶來的潛在沖突.如對于“銳華”操作系統(tǒng),添加一個“RCS_”前綴,將C 庫提供的所有標識符映射到一個帶有“RCS_”前綴的命名空間,以避免命名時的相互影響.類似的,將枚舉型定義、類型定義、結構體定義和函數(shù)定義都映射到帶有“RCS_”前綴的命名空間,具體舉例見表2.
表2 PAL 中關于“銳華”系統(tǒng)的映射關系
不同宿主平臺上C 語言對應的數(shù)據類型存在差異,PAL 并不直接使用C 語言所定義的數(shù)據類型,而是重新定義一套與平臺無關的數(shù)據類型,具體如表3.
表3 數(shù)據結構
本小節(jié)選取“銳華”操作系統(tǒng)、龍芯3a 硬件平臺,以任務相關接口為例,對PAL 的實現(xiàn)進行詳細闡述.
在實現(xiàn)方式上,受到平臺獨立[14]的啟發(fā),PAL 對各操作系統(tǒng)共有的系統(tǒng)特性和數(shù)據進行統(tǒng)一管理.各平臺的異構性則主要體現(xiàn)在接口的實現(xiàn)上.
平臺共有的定義,主要是指宏、數(shù)據結構等.平臺定義1 定義了支持浮點運算的宏,并給出了任務相關接口所需的結構體定義以及函數(shù)接口定義.
標準化接口OS_TaskCreate()用于創(chuàng)建任務,其參數(shù)定義了任務ID、任務名、任務堆棧大小、優(yōu)先級等.算法1 為“銳華”操作系統(tǒng)任務創(chuàng)建接口的實現(xiàn)代碼,具體實現(xiàn)的不同保證了平臺的異構性.
本節(jié)首先對PAL 提供的各類接口進行功能測試.通過編寫測試例程,調用抽象完成的各類接口進行正確環(huán)境和錯誤環(huán)境測試;然后對加入PAL 之后的操作系統(tǒng)進行兼容性測試.使用平臺抽象層提供的API 進行嵌入式開發(fā),在不修改代碼的前提下,該應用程序應當能夠同時運行在Linux 以及“銳華”操作系統(tǒng)上;3.3 小節(jié)對加入PAL 前后的實時性能進行比較分析.因為任務調度延遲時間是評價操作系統(tǒng)實時性的重要指標之一[15],所以選擇對其進行測量;最后,3.4 小節(jié)對PAL 的優(yōu)勢進行了分析與總結.
以任務管理接口為例,在測試例程初始化完成后,分別進行正常情況和異常情況測試.其中正常情況包括創(chuàng)建任務、根據ID 查詢任務信息、刪除任務操作,而異常測試則是指創(chuàng)建超過個數(shù)限制的任務,創(chuàng)建兩個同名任務,刪除未創(chuàng)建任務、刪除已刪除的任務操作.測試結果表明,設計的PAL 能夠完成正常情況下的需求,并對異常情況做出符合預期的反饋.
兼容性測試采用PAL 提供的標準化接口編寫測試例程,分別在Linux 系統(tǒng)與“銳華”系統(tǒng)上進行測試,測試結果如圖4 所示.這段測試程序在兩個系統(tǒng)上均運行成功并輸出正確,這表明PAL 的設計提高了應用程序的代碼重用性.
在實時任務測試中,獲取測試任務執(zhí)行前的時刻t1,將實時任務休眠時間設置為T;獲取實時任務執(zhí)行完成時的時刻記為t2,t2-t1-T就是所要測量的任務調度延遲時間.
使用上述方法對任務調度延遲時間進行測量,共測試1000 次,對數(shù)據進行初步處理后,得出結果如圖5.
對實驗數(shù)據進行分析得出,添加PAL 前任務調度延遲的平均值為0.875 ms,添加PAL 后任務調度延遲的平均值為1.094 ms.通過數(shù)據與圖表對比可以看出,添加PAL 后的任務調度延遲時間要比添加PAL 前略微增加.這是由于PAL 的引入致使系統(tǒng)多出了一個PAL 接口與宿主平臺接口間的函數(shù)調用,但添加PAL后的時間指標仍可以保持在與原有指標相同的量級.
分析以上實驗,引入PAL 的嵌入式操作系統(tǒng)在擴展了應用程序的代碼重用性后仍具有可靠的實時性.
PAL 是位于嵌入式操作系統(tǒng)與應用程序之間的獨立接口層,是一種銜接不同操作系統(tǒng)、硬件平臺與應用程序的橋梁.
首先,在平臺抽象層上進行開發(fā)可以避免嵌入式應用與操作系統(tǒng)和底層硬件的直接交互,有利于提高應用程序的健壯性.其次,平臺抽象層可以根據具體應用所需的系統(tǒng)調用來構造相應的接口,因此平臺抽象層具有良好的可裁剪性和伸縮性.最后,平臺抽象層按照系統(tǒng)的相關性對應用程序代碼進行分類,當應用適配新的宿主平臺時,只需修改少量甚至無需修改代碼即可在新平臺上運行應用程序,大大提高了開發(fā)的效率.總的來說,PAL 有利于實現(xiàn)軟硬件協(xié)同設計,促進可移植和可重用的實時嵌入式系統(tǒng)應用程序的創(chuàng)建.
圖4 兼容性測試結果
圖5 實時性測試結果
本文為嵌入式實時操作系統(tǒng)設計了一個平臺抽象層,著重介紹平臺抽象層的設計方案,并針對Linux 系統(tǒng)與“銳華”操作系統(tǒng)給出實現(xiàn)方案,最后對平臺抽象層的功能,兼容性和實時性給出測試方案.實驗證明,引入本文設計的平臺抽象層不僅能提高應用程序的可移植性,同時操作系統(tǒng)還保留有可靠的實時性.
平臺抽象層對不同操作系統(tǒng)與硬件平臺的應用程序開發(fā)接口進行抽象,給用戶開發(fā)各種嵌入式應用提供了標準化接口,極大減少移植帶來的冗余工作,并可高效重用已開發(fā)的軟件組件,有效實現(xiàn)了資源復用.