1. 程式人生 > >轉 有或無作業系統的Linux裝置驅動區別

轉 有或無作業系統的Linux裝置驅動區別

 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()函式讀寫檔案就可以訪問各種字元裝置和塊裝置,而不用管裝置的具體型別和工作方式,是非常方便的。

    不管有無作業系統,不管是SerialSend,或者write,訪問裝置都需要對暫存器進行讀寫操作,比如串列埠,在dev目錄下有個ttys0結點,我們可以通過ioctl函式對其進行讀寫操作,當然,writeread更為直接咯。而上層的應用可以對這些函式進行封裝,定義不同的介面,從而實現更多的功能。