1. 程式人生 > 其它 >Linux裝置驅動開發入門--裝置驅動程式框架

Linux裝置驅動開發入門--裝置驅動程式框架

一、Linux裝置分類

  Linux將裝置主要分為三類:字元裝置、塊裝置、網路裝置。

  1. 字元裝置:必須以序列順序依次訪問的裝置,不能讓隨機訪問裝置記憶體中某一組資料;

  2. 塊裝置:可以按照任意順序進行訪問,以塊為單位,例如硬碟、eMMc等;

  3. 網路裝置:面向資料包的接收和傳送而設計,不傾向於對應檔案系統的節點。

二、Linux裝置驅動程式與外界的介面

  1. 驅動程式於作業系統核心的介面

  2. 驅動程式與系統引導的介面

  3. 驅動程式與裝置的介面

三、根據功能劃分

  1. 驅動程式的註冊和登出。

  裝置驅動程式可以再系統啟動的時候初始化,也可以在需要的時候動態載入。

  字元裝置的初始化由chr_dev_init()完成。

  塊裝置初始化由blk_dev_init()完成。

  每個字元裝置或是塊裝置的初始化都是通過devfs_register_chrdev() 或是devfs_register_blkdev()向核心註冊,在關閉字元裝置或是塊裝置時,需要通過devfs_unregister_chrdev() 或是 devfs_register_blkdev() 從核心中登出裝置。

  2. 裝置的開啟與釋放

  裝置開啟:

  開啟裝置是由open()來完成的,例如印表機lp_open()

  裝置開啟要經過一下幾個步驟:

  (1)增加裝置使用計數

  (2)檢查裝置相關錯誤,如裝置尚未準備好類似的硬體問題

  (3)檢查是首次開啟,則初始化裝置

  (4)識別裝置號,如有必要則更新f_op指標

  (5)如果需要,分配且設定要放在filp->private_data裡的資料結構

  裝置釋放:

  關閉釋放裝置由release()來完成,例如釋放印表機是用lp_release(),而釋放終端裝置是用tty_release ().

  釋放裝置步驟如下:

  (1)釋放在filp->private_data中的open分配的記憶體。

  (2)如果是最後一次釋放,則關閉裝置。

  (3)遞減裝置使用計數。

  3. 裝置的讀寫操作

  字元裝置使用各自的read()和write()來進行資料讀寫。

  塊裝置使用 generic_file_read() 和genertc_file_write()來進行資料讀寫。

  這兩個通用函式向請求表新增讀寫請求,核心可以通過ll_rw_block()優化請求順序。由於是對記憶體緩衝區而不是設

備進行操作的,因而可以加快讀寫請求。如果記憶體緩衝區內沒有要讀入的資料或是要將寫請求寫入裝置,那麼就要真正

的執行資料傳輸。這是通過資料結構request_queue和request_fn()來完成(include/linux/blkdev.h)。

  4. 裝置的控制操作

 除了讀寫操作,有時還要控制裝置。這可以通過裝置驅動程式中的ioctl()來完成。例如IDE硬碟的控制可以通過hd_ioctl(),對光碟機的控制可以通過cdrom_ioctl()。

  與讀寫操作不同,ioctl()的用法與具體裝置密切相關。以軟碟機的floppy_ioctl()為例(drivers/block/floppy。c):

  staticintfd_ioctl(structinode*inode,

  structfile*filp,

  unsignedintcmd,

  unsignedlongparam);

  其中,cmd的取值及含義都是與軟碟機有關的,比如,FDEJECT表示彈出軟盤。

  除了ioctl(),裝置驅動程式還可能有其他控制函式,比如llseek()等。

  5. 裝置的中斷和輪詢處理

  對於不支援中斷的裝置,讀寫時需要輪詢裝置狀態,以及是否需要繼續進行資料傳輸。例如,印表機。如果裝置支援中斷,則可按照中斷方式進行。

本文摘自:https://tech.hqew.com/news_589150