在嵌入式中,有無(wú)操作系統對設備驅動(dòng)有啥不同?
一、驅動(dòng)的作用
本文引用地址:http://dyxdggzs.com/article/201801/373924.htm任何一個(gè)計算機系統的運行都是系統中軟硬件協(xié)作的結果,沒(méi)有硬件的軟件是空中樓閣,而沒(méi)有軟件的硬件則只是一堆廢鐵。硬件是底層基礎,是所有軟件得以運行的平臺,代碼最終會(huì )落實(shí)為硬件上的組合邏輯與時(shí)序邏輯;軟件則實(shí)現了具體應用,它按照各種不同的業(yè)務(wù)需求而設計,滿(mǎn)足了用戶(hù)的需求。硬件較固定,軟件則很靈活,可以適應各種復雜多變的應用??梢哉f(shuō),計算機系統的軟硬件互相成就了對方。
但是,軟硬件之間同樣存在著(zhù)悖論,那就是軟件和硬件不應該互相滲透到對方的領(lǐng)地。為了盡可能快速地完成設計,應用軟件工程師不想也不必關(guān)心硬件,而硬件工程師也難有足夠的閑暇和能力來(lái)顧及軟件。例如,應用軟件工程師在調用套接字發(fā)送和接收數據包的時(shí)候,他不必關(guān)心網(wǎng)卡上的中斷、寄存器、存儲空間、I/O端口、片選以及其他任何硬件詞匯;在使用printf()函數輸出信息的時(shí)候,他不用知道底層究竟是怎樣把相應的信息輸出到屏幕或串口。
也就是說(shuō),應用軟件工程師需要看到一個(gè)沒(méi)有硬件的純粹的軟件世界,硬件必須被透明地呈現給他們。誰(shuí)來(lái)實(shí)現硬件對應用軟件工程師的隱形?這個(gè)艱巨的任務(wù)就落在了驅動(dòng)工程師的頭上。
對設備驅動(dòng)最通俗的解釋就是“驅使硬件設備行動(dòng)” 。設備驅動(dòng)與底層硬件直接打交道,按照硬件設備的具體工作方式讀寫(xiě)設備寄存器,完成設備的輪詢(xún)、中斷處理、DMA通信,進(jìn)行物理內存向虛擬內存的映射,最終使通信設備能夠收發(fā)數據,使顯示設備能夠顯示文字和畫(huà)面,使存儲設備能夠記錄文件和數據。
由此可見(jiàn),設備驅動(dòng)充當了硬件和應用軟件之間的紐帶,它使得應用軟件只需要調用系統軟件的應用編程接口(API)就可讓硬件去完成要求的工作。在系統中沒(méi)有操作系統的情況下,工程師可以根據硬件設備的特點(diǎn)自行定義接口,如對串口定義SerialSend()、SerialRecv();對 LED 定義LightOn()、LightOff();以及對 Flash 定義FlashWrite()、FlashRead()等。而在有操作系統的情況下,設備驅動(dòng)的架構則由相應的操作系統定義,驅動(dòng)工程師必須按照相應的架構設計設備驅動(dòng),這樣,設備驅動(dòng)才能良好地整合到操作系統的內核中。
驅動(dòng)程序溝通著(zhù)硬件和應用軟件,而驅動(dòng)工程師則溝通著(zhù)硬件工程師和應用軟件工程師。隨著(zhù)通信、電子行業(yè)的迅速發(fā)展,全世界每天都會(huì )有大量的新芯片被生產(chǎn),大量的新電路板被設計,因此,也會(huì )有大量設備驅動(dòng)需要開(kāi)發(fā)。這些設備驅動(dòng),或運行在簡(jiǎn)單的單任務(wù)環(huán)境中,或運行在 VxWorks、Linux、Windows等多任務(wù)操作系統環(huán)境中,發(fā)揮著(zhù)不可替代的作用。
二、有無(wú)操作系統的區別
1)無(wú)操作系統(即裸機)時(shí)的設備驅動(dòng)
并不是任何一個(gè)計算機系統都一定要運行操作系統,在許多情況下操作系統是不要的。對于功能比較單一、控制并不復雜的系統,如公交車(chē)刷卡機、電冰箱、微波、簡(jiǎn)單的手機和小靈通等,并不需要多任務(wù)調度、文件系統、內存管理等復雜功能,單任務(wù)架構完全可以很好地支持它們的工作。一個(gè)無(wú)限循環(huán)中夾雜對設備中斷的檢測或者對設備的輪詢(xún)是這種系統中軟件的典型架構。裸機的實(shí)現就有點(diǎn)類(lèi)似單片機(MCU)了,盡管單片機的寄存器沒(méi)有那么的多,如果會(huì )裸機驅動(dòng),我想,應該能勝任單片機的工作了,呵呵。
在這樣的系統中,雖然不存在操作系統,但是設備驅動(dòng)是必須存在的。一般情況下,對每一種設備驅動(dòng)都會(huì )定義為一個(gè)軟件模塊,包含.h文件和.c文件,前者定義該設備驅動(dòng)的數據結構并聲明外部函數,后者進(jìn)行設備驅動(dòng)的具體實(shí)現。書(shū)中例舉了一個(gè)串口驅動(dòng)serial.c serial.h,主要是配置GPIO,串口控制寄存器,以及串口的收發(fā)(讀寫(xiě))寄存器,而這幾個(gè)配置都是自定義函數實(shí)現的,比如串口的寫(xiě)(發(fā))SerialSend 函數等。
其他模塊需要使用這個(gè)設備的時(shí)候,只需要包含設備驅動(dòng)的頭文件 serial.h,然后調用其中的外部接口函數即可。如我們要從串口上發(fā)送字符串“Hello World”,使用函數SerialSend( " Hello World ",11)即可。
由此可見(jiàn),在沒(méi)有操作系統的情況下,設備驅動(dòng)的接口被直接提交給了應用軟件工程師, 應用軟件沒(méi)有跨越任何層次就直接訪(fǎng)問(wèn)了設備驅動(dòng)的接口。 設備驅動(dòng)包含的接口函數也與硬件的功能直接吻合, 沒(méi)有任何附加功能。
有的工程師把單任務(wù)系統設計成設備驅動(dòng)和具體的應用軟件模塊處于同一層次(即應用程序也在比如serial.c中實(shí)現),這顯然是不合理的,不符合軟件設計中高內聚低耦合的要求。
另一種不合理的設計是直接在應用中操作硬件的寄存器(單獨一個(gè)main.c,所有功能都在一個(gè)函數中實(shí)現,不采用其他任何接口/函數),而不單獨設計驅動(dòng)模塊,這種設計意味著(zhù)系統中不存在或未能充分利用可被重用的驅動(dòng)代碼。
2)有操作系統時(shí)的設備驅動(dòng)
無(wú)操作系統時(shí)的設備驅動(dòng)中的設備驅動(dòng)直接運行在硬件之上,不與任何操作系統關(guān)聯(lián)。當系統中包含操作系統后,設備驅動(dòng)會(huì )變得怎樣?
首先,無(wú)操作系統時(shí)設備驅動(dòng)的硬件操作工作仍然是必不可少的, 沒(méi)有這一部分,設備驅動(dòng)不可能與硬件打交道。
其次,我們還需要將設備驅動(dòng)融入內核。為了實(shí)現這種融合,必須在所有的設備驅動(dòng)中設計面向操作系統內核的接口,這樣的接口由操作系統規定,對一類(lèi)設備而言結構一致,獨立于具體的設備。
由此可見(jiàn),當系統中存在操作系統的時(shí)候,設備驅動(dòng)變成了連接硬件和內核的橋梁。操作系統的存在勢必要求設備驅動(dòng)附加更多的代碼和功能(以我看,主要是提供了很多結構),把單一的“驅使硬件設備行動(dòng)”變成了操作系統內與硬件交互的模塊,它對外呈現為操作系統的API,不再給應用軟件工程師直接提供接口。有了操作系統之后,設備驅動(dòng)反而變得復雜,那要操作系統干什么?
首先,一個(gè)復雜的軟件系統需要處理多個(gè)并發(fā)的任務(wù),沒(méi)有操作系統,想完成多任務(wù)并發(fā)是很困難的。
其次,操作系統給我們提供內存管理機制。一個(gè)典型的例子是,對于多數含 MMU的處理器而言,Windows、Linux 等操作系統可以讓每個(gè)進(jìn)程都獨立地訪(fǎng)問(wèn) 4GB的內存空間。
上述優(yōu)點(diǎn)似乎并沒(méi)有體現在設備驅動(dòng)身上,操作系統的存在給設備驅動(dòng)究竟帶來(lái)了什么好處呢?
簡(jiǎn)而言之,操作系統通過(guò)給設備驅動(dòng)制造麻煩來(lái)達到給上層應用提供便利的目的。如果設備驅動(dòng)都按照操作系統給出的獨立于設備的接口而設計,應用程序將可使用統一的系統調用接口來(lái)訪(fǎng)問(wèn)各種設備。對于類(lèi)UNIX的VxWorks、Linux等操作系統而言,應用程序通過(guò)write()、read()等函數讀寫(xiě)文件就可以訪(fǎng)問(wèn)各種字符設備和塊設備,而不用管設備的具體類(lèi)型和工作方式,是非常方便的。
不管有無(wú)操作系統,不管是SerialSend,或者write,訪(fǎng)問(wèn)設備都需要對寄存器進(jìn)行讀寫(xiě)操作,比如串口,在dev目錄下有個(gè)ttys0結點(diǎn),我們可以通過(guò)ioctl函數對其進(jìn)行讀寫(xiě)操作,當然,write、read更為直接咯。而上層的應用可以對這些函數進(jìn)行封裝,定義不同的接口,從而實(shí)現更多的功能
評論