對設備驅動通俗的解釋就是“驅使硬件設備行動”。設備驅動與底層硬件直接打交道,按照硬件設備的具體工作方式讀寫設備寄存器,完成設備的輪詢、中斷處理、DMA通信,進行物理內存向虛擬內存的映射,終使通信設備能夠收發數據,使顯示設備能夠顯示文字和畫面,使存儲設備能夠記錄文件和數據。此可見,設備驅動充當了硬件和應用軟件之間的紐帶,它使得應用軟件只需要調用系統軟件的應用編程接口(API)就可讓硬件去完成要求的工作。在系統中沒有操作系統的情況下,工程師可以根據硬件設備的特點自行定義接口,自己為函數命名。而在有操作系統的情況下,設備驅動的架構則由相應的操作系統定義,驅動工程師必須按照相應的架構設計設備驅動,這樣,設備驅動才能良好地整合到操作系統的內核中。
二、無操作系統的設備驅動
并不是任何一個計算機系統都一定要運行操作系統,在許多情況下操作系統是不必要的。對于功能比較單一、控制并不復雜的系統并不需要多任務調度、 文件系統、 內存管理等復雜功能,用單任務架構完全可以很好地支持它們的工作。 一個無限循環中夾雜對設備中斷的檢測或者對設備的輪詢是這種系統中軟件的典型架構。如圖:
由此可見,在沒有操作系統的情況下, 設備驅動的接口被直接提交給了應用軟件工程師, 應用軟件沒有跨越任層次就直接訪問了設備驅動的接口。 設備驅動包含的接口函數也與硬件的功能直接吻合, 沒有任何附加功能。如圖:
操作系統的存在勢必要求設備驅動附加更多的代碼和功能,把單一的“驅使硬件設備行動”變成了操作系統內與硬件交互的模塊,它對外呈現為操作系統的API,不再給應用軟件工程師直接提供接口。
首先,一個復雜的軟件系統需要處理多個并發的任務,沒有操作系統,想完成多任務并發是很困難的。其次,操作系統給我們提供內存管理機制。一個典型的例子是,對于多數含MMU的處理器而言,Windows、Linux等操作系統可以讓每個進程都獨立地訪問4GB的內存空間。操作系統通過給設備驅動制造麻煩來達到給上層應用提供便利的目的。如果設備驅動都按照操作系統給出的獨立于設備的接口而設計,應用程序將可使用統一的系統調用接口來訪問各種設備。對于Linux 等操作系統而言, 應用程序通過 write()、read()等函數讀寫文件就可以訪問各種字符設備和塊設備,而不用管設備的具體類型和工作方式,
四、linux設備驅動
4.1設備的分類及特點
計算機系統的硬件主要由CPU、存儲器和外設組成。目前,芯片的集成度越來越高,往往在CPU內部就集成了存儲器和外設適配器。ARM、PowerPC、MIPS等處理器都集成了UART、I2C控制器、USB控制器、SDRAM控制器等,有的處理器還集成了片內 RAM 和 Fl ash 。驅動針對的對象是存儲器和外設(包括 CPU 內部集成的存儲器和外設) ,而不是針對 CPU 核。Linux 將存儲器和外設分為 3 個基礎大類:
字符設備;
塊設備;
網絡設備
字符設備指那些必須以串行順序依次進行訪問的設備,如觸摸屏、磁帶驅動器、鼠標等。塊設備可以用任意順序進行訪問,以塊為單位進行操作,如硬盤、軟驅等。字符設備不經過系統的快速緩沖,而塊設備經過系統的快速緩沖。但是,字符設備和塊設備并沒有明顯的界限,如Flash設備符合塊設備的特點,但是我們仍然可以把它作為一個字符設備來訪問。字符設備和塊設備的驅動設計呈現出很大的差異,但是對于用戶而言,他們都使用文件系統的操作接口open()、close()、read()、write()等函數進行訪問。在 Linux 系統中,網絡設備面向數據包的接收和發送而設計,它并不對應于文件系統的節點。 內核與網絡設備的通信和內核與字符設備、 塊設備的通信方式完全不同。
4.2Linux設備驅動與整個軟硬件系統的關系除網絡設備外,字符設備與塊設備都被映射到Linux文件系統的文件和目錄,通過文件系統的系統調用接口open()、write()、read()、close()等函數即可訪問字符設備和塊設備。所有的字符設備和塊設備都被統一地呈現給用戶。塊設備比字符設備復雜,在它上面會首先建立一個磁盤/Flash 文件系統, 如 F AT、 Ext3、 Y AFFS、JFFS 等。F AT、Ext3、Y AFFS、JFFS 規范了文件和目錄在存儲介質上的組織。
應用程序可以使用 Linux 的系統調用接口編程,也可以使用 C 庫函數,出于代碼可移植性的考慮,后者更值得推薦。C 庫函數本身也通過系統調用接口而實現,如 C庫函數中的 fopen()、 fwrite()、 fread()、 fclose()分別會調用操作系統 API 的 open()、 write()、read()、close()函數。
編寫 Linux 設備驅動要求工程師具有良好的硬件基礎,懂得 SRAM、Flash、SDRAM、磁盤的讀寫方式,UART、I2C、USB 等設備的接口,輪詢、中斷、DMA 的原理,PCI 總線的工作方式以及 CPU 的內存管理單元(MMU)等。
編寫 Linux 設備驅動要求工程師具有良好的 C 語言基礎, 能靈活地運用 C 語言的結構體、指針、函數指針及內存動態申請和釋放等。
編寫 Linux 設備驅動要求工程師具有一定的 Linux 內核基礎,雖然并不要求工程師對內核各個部分有深入的研究,但至少要了解設備驅動與內核的接口,尤其是對于塊設備、網絡設備、Flash 設備、串口設備等復雜設備。
編寫 Linux 設備驅動要求工程師具有良好的多任務并發控制和同步的基礎,因為在設備驅動中會大量使用自旋鎖、互斥、信號量、等待隊列等并發與同步機制。