天天看點

嵌入式有無作業系統的差別

物聯網裝置.jpg

有無作業系統的差別

1)無作業系統(即裸機)時的裝置驅動

并不是任何一個計算機系統都一定要運作作業系統,在許多情況下作業系統是不要的。對于功能比較單一、控制并不複雜的系統,如公共汽車刷卡機、電冰箱、微波、簡單的手機和小靈通等,并不需要多任務排程、檔案系統、記憶體管理等複雜功能,單任務架構完全可以很好地支援它們的工作。一個無限循環中夾雜對裝置中斷的檢測或者對裝置的輪詢是這種系統中軟體的典型架構。裸機的實作就有點類似單片機(MCU)了,盡管單片機的寄存器沒有那麼的多,如果會裸機驅動,我想,應該能勝任單片機的工作了,呵呵。

在這樣的系統中,雖然不存在作業系統,但是裝置驅動是必須存在的。一般情況下,對每一種裝置驅動都會定義為一個軟體子產品,包含.h檔案和.c檔案,前者定義該裝置驅動的資料結構并聲明外部函數,後者進行裝置驅動的具體實作。書中例舉了一個序列槽驅動serial.c serial.h,主要是配置GPIO,序列槽控制寄存器,以及序列槽的收發(讀寫)寄存器,而這幾個配置都是自定義函數實作的,比如序列槽的寫(發)SerialSend 函數等。

其他子產品需要使用這個裝置的時候,隻需要包含裝置驅動的頭檔案 serial.h,然後調用其中的外部接口函數即可。如我們要從序列槽上發送字元串“Hello World”,使用函數SerialSend( " Hello World ",11)即可。

由此可見,在沒有作業系統的情況下,裝置驅動的接口被直接送出給了應用軟體工程師, 應用軟體沒有跨越任何層次就直接通路了裝置驅動的接口。 裝置驅動包含的接口函數也與硬體的功能直接吻合, 沒有任何附加功能。

有的工程師把單任務系統設計成裝置驅動和具體的應用軟體子產品處于同一層次(即應用程式也在比如serial.c中實作),這顯然是不合理的,不符合軟體設計中高内聚低耦合的要求。

另一種不合理的設計是直接在應用中操作硬體的寄存器(單獨一個main.c,所有功能都在一個函數中實作,不采用其他任何接口/函數),而不單獨設計驅動子產品,這種設計意味着系統中不存在或未能充分利用可被重用的驅動代碼。

2)有作業系統時的裝置驅動

無作業系統時的裝置驅動中的裝置驅動直接運作在硬體之上,不與任何作業系統關聯。當系統中包含作業系統後,裝置驅動會變得怎樣?

首先,無作業系統時裝置驅動的硬體操作工作仍然是必不可少的, 沒有這一部分,裝置驅動不可能與硬體打交道。

其次,我們還需要将裝置驅動融入核心。為了實作這種融合,必須在所有的裝置驅動中設計面向作業系統核心的接口,這樣的接口由作業系統規定,對一類裝置而言結構一緻,獨立于具體的裝置。

由此可見,當系統中存在作業系統的時候,裝置驅動變成了連接配接硬體和核心的橋梁。作業系統的存在勢必要求裝置驅動附加更多的代碼和功能(以我看,主要是提供了很多結構),把單一的“驅使硬體裝置行動”變成了作業系統内與硬體互動的子產品,它對外呈現為作業系統的API,不再給應用軟體工程師直接提供接口。有了作業系統之後,裝置驅動反而變得複雜,那要作業系統幹什麼?

首先,一個複雜的軟體系統需要處理多個并發的任務,沒有作業系統,想完成多任務并發是很困難的。

其次,作業系統給我們提供記憶體管理機制。一個典型的例子是,對于多數含 MMU的處理器而言,Windows、Linux 等作業系統可以讓每個程序都獨立地通路 4GB的記憶體空間。

上述優點似乎并沒有展現在裝置驅動身上,作業系統的存在給裝置驅動究竟帶來了什麼好處呢?

簡而言之,作業系統通過給裝置驅動制造麻煩來達到給上層應用提供便利的目的。如果裝置驅動都按照作業系統給出的獨立于裝置的接口而設計,應用程式将可使用統一的系統調用接口來通路各種裝置。對于類UNIX的VxWorks、Linux等作業系統而言,應用程式通過write()、read()等函數讀寫檔案就可以通路各種字元裝置和塊裝置,而不用管裝置的具體類型和工作方式,是非常友善的。

繼續閱讀