摘 要:針對嵌入式系統的實際特性,著重從系統的角度提出構造一個嵌入式應用程序的開發架構,也可以稱為開發框架。該開發架構是以基于組件的方法來開發嵌入式應用程序的,其主要研究系統結構規約、系統行為規約、組件配置和執行、程序產生和系統配置等幾個關鍵問題。研究的結果將指導一個分布嵌入式應用程序開發框架的構造。
關鍵詞:嵌入式軟件; 組件; 框架
中圖分類號:TP311文獻標志碼:A
文章編號:1001—3695(2007)03—0062—04
隨著嵌入式系統的廣泛應用,作為嵌入式系統主要部分的嵌入式軟件的需求也越來越大,但因為嵌入式系統的特性,如實時性、安全性等,在不同的嵌入式硬件平臺上開發出高質量、符合各種要求的嵌入式軟件的困難也越來越大。由于激烈的市場競爭,嵌入式系統的開發不僅強調要減少開發的時間和費用,更重要的是要求能開發出高質量的嵌入式應用程序。這些嵌入式軟件不僅要符合嵌入式系統穩定性、無錯性、實時性等要求,還要求軟件的可重用性、可配置性和擴展性,以提高嵌入式應用程序的開發效率和質量?,F在開發嵌入式軟件一般使用較低級的語言,如C語言甚至匯編語言。如果一個嵌入式系統函數很簡單,用這些語言來開發是比較合適的,但隨著嵌入式硬件功能的不斷增強和嵌入式軟件需求的不斷變化,使用這些低級方法來開發嵌入式應用程序導致了很多不好的后果,如開發過程中低效重復的工作將不斷出現,軟件生產周期難以控制且軟件質量難以保證。這些現狀迫切需要嵌入式軟件的開發人員遵循軟件工程的開發原則,采用一些更高級的軟件開發技術來開發嵌入式應用程序。這些技術有很多,如基于模型的開發技術、基于組件的開發技術等。只有這樣,才能在日益嚴峻的開發環境下,開發出不僅能滿足市場需求,也能滿足嵌入式系統特性的高質量、高效率的嵌入式應用程序。
針對嵌入式系統的實際特性,本文著重從系統的角度提出構造一個嵌入式應用程序的開發架構,也可以稱為開發框架。開發這樣一個使用開發嵌入式應用程序的架構及其相關的軟件設計方法是一項十分復雜的工程任務。到目前為止,國內外還沒有一個公認的方法能夠解決此問題,這主要是由于嵌入式系統的特殊性,導致常用軟件開發方法并不適用于嵌入式軟件開發。本文的開發架構是以基于組件的方法來開發嵌入式應用程序的。
1 組件技術
組件可以被認為是面向對象和其他軟件技術的化身。區分組件和其他先前的技術有四個原則[1],即封裝(Encapsulation)、多態性(Polymorphism)、后期連接(Late Binding)和安全性(Safety)。這個列表與面向對象是重復的,除了它刪除了繼承(Inheritance)這個重點。在組件思想中,繼承是緊密耦合的白盒(Whitebox)關系,它對于大多數的包裝和重復使用都是不適合的。作為代替,組件通過調用其他對象和組件重復使用功能,代替了從它們那兒繼承。在組件術語中,這些調用稱為委托(Delegations)。
根據慣例,所有組件都擁有與其實現對應的規范。這種規范定義了組件的封裝(如為其他組件提供的公共接口)。組件規范的重復使用是多態性的一種形式,它受到高度鼓勵。理想情形是,組件規范是本地的或全局的標準,它在系統、企業或行業中被廣泛地重復使用。
組件利用合成(Composition)來建立系統。在合成中,兩個或多個組件集成到一起以建立一個更大的實體,而它可能是一個新組件、組件框架或整個系統。合成是組件的集成。結合的組件從要素組件中得到了聯合的規范。
如果組件符合了客戶端調用和服務的規范,那么它們不需要額外編寫代碼就能夠實現交互操作(Interoperate),這一般被稱為即插即用(PlugandPlay)集成。在運行時間執行時,這是后期連接的一種形式,如某個客戶端組件可以通過在線目錄發現組件服務器(類似CORBA Trader服務)。組件符合客戶端和服務接口規范后,就能夠建立彼此之間的運行時綁定,并通過組件的下部構造無縫的交互作用。
把組件技術應用到嵌入式系統軟件的開發中,將極大地促進嵌入式軟件開發效率的提高,改善嵌入式軟件質量。
但是當前困擾嵌入式開發人員的是將組件技術應用到嵌入式軟件開發中還有很多亟待解決的問題。
2 系統結構規約
很多嵌入式系統都是用基于過程的開發技術,這種開發技術的規約主要是對靜態或者動態過程時序進行規范說明。可以將一個基于過程的嵌入式系統形容為在一個實時核心和靜態調度下運行一組相關的過程,或稱為任務。基于過程的規約有一個明顯的缺點,即它重視的是實時系統的功能分解,而不是結構分解。換句話說,基于過程的軟件開發技術是一個以功能為中心的軟件開發技術,它強調將系統按功能分解以便于實現。這種規約主要說明時序分析中的問題,這導致最后的實現系統既不是開放的,也不容易重新構造,特別是對一些靜態時序過程來說。
相反,基于對象的規約強調結構的分解,這樣容易使系統具有開放性,也容易被重新構造。這樣的系統由一些相互作用的組件構成,這些組件包括函數模塊和接口對象,接口對應著嵌入式系統的實時任務。但同時不幸的是,基于對象的設計方法經常忽視了時間行為和時序分析,而這些特性在硬實時系統中是十分重要的。
基于對象的軟件設計方法是現在比較流行的應用程序設計方法,它有一些基本原則,如對象或組件的封裝、聚合和組合,從實質上說,這也可以稱為是基于組件的設計方法。該設計方法的一個主要問題是要建立大量非形式化的標準應用程序對象。在許多軟件設計中,系統設計者必須為每一個特定的應用程序定義系統對象和系統類,并將這些類和對象應用于實現組件的功能和接口中。從某種程度來說,也就是實現嵌入式系統的實時任務。有時一個組件就可以實現一個任務,有時則需要幾個組件合作來實現一個任務,相反有時幾個任務可以由一個組件實現。
有些學者[2]認為,一個軟件設計方法可以將不同類型的規約組合成一個混合方法,考慮到系統結構的每個特性,如時間性、結構性等。這導致出現了適用于混合結構的軟件設計方法,它們既是基于對象的,也是基于過程的。在這樣的系統中,系統可以由一些相互作用的對象構成,每個對象又封裝了一個或多個控制線程。這些線程可以調用對象的操作,同樣,對象間也可以互相調用彼此的操作。
由于標準規約和設計嚴重限制了組件的重用性,所以迫切需要發展一個形式化的開發框架。這個框架定義了可以用來開發嵌入式應用程序的組件的規約,這些組件可以被重用??紤]到現在大部分嵌入式系統主要是控制和監控系統,正確實現此框架的方法是運用控制工程領域中的分解原則來規范這些軟件組件,而不是僅憑開發人員的經驗直覺來開發這些組件。上述方法在一些工業軟件中已經得到某種程度的實現,但相對來說程度較低。
在系統結構的規范說明中,組件交互是另一個需要解決的主要問題?,F在不管是基于過程還是基于對象的系統都有很多交互模式,如客戶機—服務器模式(C/S)、生產者—客戶模式(ProductConsumers)和出版者—訂戶模式(PublisherSubscribers)??蛻魴C—服務器模式應用得比較廣泛,如計算機通信系統,它的局限性主要是通信模塊化和只能點對點交互;生產者—客戶模式被認為是比較適合嵌入式實時系統,主要是因為它是非模塊的,同時也支持一對多的交互;出版者—訂戶模式綜合了前兩者的特點,在實際中有很多應用。這些模式可以通過組件的接口來實現,而組件的接口一般在組件接口模型中進行定義。嵌入式系統主要有兩種這樣的模型:①接口模型根據輸入和輸出來規約組件接口,而不論一個組件的輸出是否直接與一個或多個其他組件的輸入直接相連;②基于端口的對象通過相連在一起的輸入和輸出端口進行交互,如通過一個共享內存來實現。模型②是專門開發應用在機器人應用程序中的,但相似的模型在很多應用程序中被廣泛應用?;诙丝诘膶ο筇峁┝烁叨鹊倪m應性,但同時其應用也導致模型相對比較復雜,如使模型圖十分混亂,這是因為它需要很明確的規約應用程序使所有的端口與端口連接。這個問題通過隱含地定義I/O緩存和輸入、輸出來克服,這樣,模型輸入函數模塊圖就比較容易理解。在這樣的情況下,I/O緩存在相互作用的功能模塊實例的相應執行記錄中被定義,而不管一個輸入變量是否能從相應的輸出中得到。然而,這種技術是直接應用于低水平的組件如函數塊的,它并不適合應用在嵌入式應用程序中。在這樣的情況下,我們需要使用特殊目的組件,如服務接口函數塊。
分布式應用程序需要一些高水平的組件或功能單元,它們是系統軟件的代理者,可以說是系統中能自治的子系統,如感應器、控制器、傳感器等,這些子系統分布在不同的網絡節點,相互之間進行通信完成不同的任務。所以我們可以借鑒控制工程中的方法,來構造適用于分布式嵌入式系統的組件,從高一級的層面上構造嵌入式應用程序。這時就需要擴展新的軟件技術,使我們使用的軟件功能單元有一個統一的形式,它們之間不管處在什么樣的物理環境中,都能夠透明地進行通信。為了達到這個目的,這也同時要求我們開發出一種新的通信協議來支持在相互聯系的功能單元之間信號可以透明傳輸。
3 系統行為規約
在操作級別上的規約中,有一個矛盾存在于不同的范例之間,如事件驅動操作與時間驅動操作之間、控制流程模型與數據流程模型之間。這是因為一些架構和設計方法強調在相互聯系的組件及子系統中應該是事件驅動反應和控制流程,而另外一些則強調時間驅動反應和數據流程。前一種形式的軟件架構一般應用在離散事件驅動系統,而后一種架構則應用在連續控制系統。這種情況也反映了在連續系統和離散系統建模及設計中的差異,這在控制工程領域是比較普遍的。
然而這種系統模型上的差異一般都是人為規定的,與現實不符。因為在現實世界中,不管它們主要處理離散系統還是連續系統,每個系統差不多都是混合的。這在很多復雜的混合控制系統和應用程序上表現得十分明顯。例如,一個離散控制系統可以用功能模塊圖來表達,同樣,一個連續控制系統可以完全用狀態機來規范說明,雖然對于這兩種控制系統而言,這不是一種適合它們的規約方法。一個離散事件驅動系統可以用一個事件驅動同步狀態機來規約和實現,相反地,一個時間驅動行為可以被看成是一個時間驅動行為的特例。
同步時間驅動實現受到了實時系統工程師的青睞,這是因為這樣的系統有周期任務執行模式,這也是在現在實時調度理論中用來預測任務響應時間分析技術的一個主要先決條件。該系統不僅受到實時系統工程師的關注,同樣也受到控制系統工程師的關注,這是因為絕大部分工業控制系統都是連續的和順序的,它們都是由周期性時間事件觸發的同步系統。
上面這些討論已經簡單地說明了用來規約系統行為的不同范例的二元性。但是,現在還沒有一個模型能綜合系統行為的反應性和轉換性,而這些又都是實際系統的固有特性,特別是對一些復雜的控制系統更是如此?,F在有一些學者正在試圖解決這個問題,如加利福尼亞大學正在進行的一個MoBIES計劃[3]。該計劃將許多計算模型綜合到一個混合基于對象的框架中,這些計算模型不僅包括一些操作模型,如狀態機、數據流程圖,還包括過程交互和執行模型等。但這個框架的缺點也很明顯,由于加入了多種計算模型,導致整個框架十分復雜,其中組件接口的多態性對于實際操作顯得過于煩瑣。
另外一個嘗試解決這個問題的例子是標準IEC61499[4]。在這個標準中,事件驅動和數據轉換綜合成低級組件,如功能塊,對于每個功能塊,事件驅動行為根據輸入/輸出時間的一個有限子集進行規約,這個子集是通過功能塊的接口規約來進行定義的。相同地,事件驅動行為也可規約成狀態轉換圖。因此就有可能重新構造狀態機,而不用重新設計和實現功能塊。這種低級組件限制了組件的充分復用性,因為一般情況下,一個功能塊希望能運行在不同的環境中,如一個被狀態轉換圖規約了行為的復雜模型控制器,其操作狀態可能會由于實際情況的不同而導致其功能塊的代碼不一樣。在這種情況下,可能會由于情況的不同而編輯不同的功能塊,雖然它們的狀態轉換圖是相同的。解決的辦法是將狀態轉換邏輯通過一個高級組建來實現,如一個狀態機,它能執行不同操作模式下的功能塊和功能塊圖。這實際上是一個混合狀態機,它包含了組件行為的反應性和轉換性。它能夠最終封裝成一個可重構類狀態機的功能塊,可以將其啟用來實現嵌入式應用程序的復雜行為。
4 組件調度和執行
組件行為既可以映射為嵌入式系統的實時過程,也可以映射為實時任務。這些任務是在一個多任務和可能是多節點的分布式環境下并發執行的。這又引出了操作行為的一個重要問題,即過程時序調度和執行問題。過程調度和執行提供了一個操作環境,保證了任務在一個規定時限內執行。當這些過程執行的是一個復雜系統的一部分過程時,這將是一個十分復雜的問題,尤其當運行在一個分布式系統中時,情況變得更加復雜。因為在分布式系統中,計算和通信任務必須在不同的環境中運行,如網絡節點、通信媒體等。然而許多情況下,仍然被要求采用一種時序調度機制來保證為應用程序任務提供一個安全的操作環境。例如,在一個嚴格的實時條件約束下,仍然要求能預測和保證系統的行為。
提供一個可靠的嵌入式系統主要有兩種基本的過程時序調度方法,即靜態時序調度和可預測的動態時序調度。靜態時序調度方法被廣泛應用于各種可靠的實時系統軟件領域,如航空、軍事和汽車行業。這種方法通常使用時間觸發結構來描述。同樣,在基于組件的設計方法中,本文也廣泛使用這種方法[5]。然而,這種方法有一個主要的缺點,即使用靜態時序調度的系統很難再進行重新構造和維護。這就與在構造嵌入式系統時要求系統支持大規模的軟件復用和支持可重新配置的需求是相矛盾的。
相對靜態時序調度來說,動態時序調度是一種更有前途的方法。這種方法定義了一個指導方針,即它是一種根據上下文環境而提前預測任務執行和交互的調度方法,簡單地說就是一種基于優先權的調度方法。然而,這種方法要求我們去構造一個安全的實時內核,它能為應用程序任務提供一個安全的且可預測的環境。換句話說,這個內核應具有以下一些特征:可預測的任務調度、安全的任務交互和可預測的內核行為。很可惜的是,現有的一些實時內核并不能滿足這些特征,如絕大多數現行的實時內核都是使用鏈表隊列來實現的,這導致了這些實時內核會產生內核抖動(Jitter)[6]。消除內核抖動可以準確預測任務響應時間,從而在設計過程中考慮內核運行效果。
另一方面,抗抖動(Jitterfree)操作可以通過強制任務在一個最差運行時間限制內運行來擴展到應用程序任務。這可以使我們得到一個高度可預測的系統行為,最終大幅度提高系統的可測試性。另一種選擇是在一個混合實時內核中使用靜態調度和動態調度兩種方法。
然而,最近形成了一個更好的方法,即同步多重作業處理——一個強大且一流的簡單計算概念模型。在這個模型下,作業的I/O驅動是在精確說明的定時實例中自動調用執行的(即作業釋放和最終期限實例),應用作業在優先權驅動和中止內核緊張的環境下執行。然而,只要作業在最終期限前結束,執行內核緊張就能有效地消除。這使得可能設計出一個結合動態調度的可預見的釋放緊張操作高度內在適應性的實時系統,且具有靜態調度系統的特征。
5 程序生成和系統配置
最近在基于組件的嵌入式系統的設計中出現了兩種方法:
(1)遵循傳統的開發路線,即首先構造一個模型和一個快速原型系統,然后再根據這個模型和原型系統一步步生成嵌入式應用程序。這種方法可以被認為是一種使用框架和源代碼組件庫來構造嵌入式軟件。可以在很多文獻中發現這種方法。
然而,這種方法一個最嚴重的缺點就是它不能提供充分的支持來進行系統重新配置。這是因為它需要生成和編輯新的代碼,而這些代碼后來被下載到嵌入式目標系統。而且,這個過程主要是通過運用現有的設計方法和語言,如UML和C++來實現的。這導致一個結果,即產生的嵌入式軟件在運行時需要大量的處理能力和內存,與嵌入式軟件的運行環境極不相配。當然,現在也有一些可以用來在低端微控制器上的編程工具,它們可以生成C代碼。但可惜的是,它們不能充分支持模塊化和硬實時操作。
(2)借鑒了許多年前發展起來的一些工業自動化系統的開發經驗。這種方法的特點就是采用形式化框架系統和預制的可執行組件庫來構造嵌入式軟件,適用于那些沒有強大的處理能力和大容量內存的嵌入式系統。這是因為每個組件在構造時不僅考慮到它的功能特點,還考慮到它的資源需求,如容量需求和執行時間。這樣一來,由它構造的嵌入式系統軟件不僅實現了必需的功能,還能適應嵌入式系統的特殊性,如實時性等。利用這種方法,可以構造一些基本功能組件,由此再生成一些低端的組件原碼,從而順利地構造出嵌入式系統軟件。
這種方法已經在一些嵌入式系統軟件開發中得到了應用,如在StateWORKs[7]計劃中,可以看到一種稱為可重配置狀態機的方法,但這種方法不支持功能塊的開發。
軟件的可配置性是保證軟件質量的一個最好的選擇,并且也是在工業化嵌入式開發階段構造好的嵌入式軟件的一個先決條件。它是系統配置的一部分,可以在嵌入式軟件開發改變高層軟件架構時,保證代碼能自動適應這種變化,從而極大地方便開發工作。
近年來,系統的可配置性在嵌入式系統開發領域越來越得到重視,這是因為它為開發提供了反復迭代的機會,而不像以前開發嵌入式系統時,一旦代碼進入目標系統,就很難再進行修改。
6 分布嵌入式軟件框架
上述的討論可以指導構造一個分布式嵌入式軟件開發框架。這個開發框架具有以下一些特征:
(1)一個分布式嵌入式系統可以由一些功能單元組成,如軟件代理可以對應于一些子系統,如傳感器、執行器、控制器和工作站等。這些功能單元可以被看作是一些大規模的軟件集成電路,它們可以被集合在一起形成一個具有特殊功能的應用軟件。
(2)每個功能單元封裝了一個或多個任務,而且每個功能單元又能由一些預制的基本組件構成,每個基本組件只完成一個最基本的任務。
(3)復雜任務行為可以用一個混合狀態機來規范說明,這個混合狀態機是一個分層的模型,它可描述系統行為的反應和轉換模式。因此,可以用這個模型來規范說明范圍很廣的嵌入式應用軟件,如離散的、連續的或混合控制系統,還可以是一個信號處理系統。這個混合狀態機模型最終可以由一些可重新配置的類狀態機的功能塊來實現。
(4)每個功能單元通過信號與系統外部系統或其他功能單元進行交互(也稱這些信號為消息)。這些信號的類型有很多種,如溫度、壓力等,它通過輸入和輸出信號驅動器進行轉換,這些信號驅動器是一些特殊的類。通過這些信號驅動器,可以構造一個通信協議來保證每個功能單元通過信號與系統外部系統或其他功能單元進行交互,而不管這些功能單元位于哪個網絡節點處。換一種角度來看,這些信號驅動器也可認為是一些接口組件。
(5)每個功能單元的信號驅動器也可以被看成是一些特殊的I/O類,它可以在一個特定的時間被喚醒,前提是有一個信號傳來,這些信號來自于外部系統或其他的功能單元。另一種情況是它可在一個系統行為執行的開始或結束時被喚醒,從而為這些系統行為執行提供參數。
7 總結
嵌入式軟件面臨著規模大、復雜性高而開發周期相對較短、必須具備可定制和演化的能力等挑戰,因此一個重用性高、擴展性和維護性好的軟件框架顯得非常必要。上面的分析簡要說明了構造一個分布嵌入式系統框架的要求:這個框架可以通過一個定義好的、分層次、可復用和可配置組件庫來支持一個開放的軟件體系結構;另一方面,在一個時間和安全要求高的應用軟件中支持可預測和確定性的行為,同時不能犧牲適應性;在操作水平上,這個框架可以提供模型,該模型能充分規范說明一系列混合應用軟件的系統行為;最后要求的是這個框架的模型技術和符號要容易被嵌入式領域專家所理解。在這些要求的前提下,本文重點分析了將組件技術應用到嵌入式軟件開發中需要解決的幾個關鍵問題。分析的結果將有助于我們構造一個基于組件的嵌入式軟件開發框架。未來的工作將在此分析的基礎上構造一個實際的框架,也可以說是一個半成品,利用此框架,能高效地構造出高質量的嵌入式應用程序。
本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文。