驅動進化之路:匯流排裝置驅動模型
文章目錄
1 驅動編寫的3種方法
以 LED 驅動為例:
1.1 傳統寫法
特點如下:
- 使用哪個引腳,怎麼操作引腳,都寫死在程式碼中。
- 最簡單,不考慮擴充套件性,可以快速實現功能。
- 修改引腳時,需要重新編譯。
1.2 匯流排裝置驅動模型
先看一下相關結構體定義:
特點如下:
- 引入 platform_device/platform_driver,將“資源”與“驅動”分離開來。
- 程式碼稍微複雜,但是易於擴充套件。
- 冗餘程式碼太多,修改引腳時裝置端的程式碼需要重新編譯。
- 更換引腳時,上圖中的 led_drv.c 基本不用改,但是需要修改 led_dev.c
1.3 裝置樹
特點如下:
- 通過配置檔案──裝置樹來定義“資源”。
- 程式碼稍微複雜,但是易於擴充套件。
- 無冗餘程式碼,修改引腳時只需要修改 dts 檔案並編譯得到 dtb 檔案,把它傳給核心。
- 無需重新編譯核心/驅動。
2 在 Linux 中實現“分離”:Bus/Dev/Drv 模型
2.1 模型
2.2 driver和device的匹配規則
最先比較: platform_device. driver_override 和 和 platform_driver.driver.name。可以設定 platform_device 的 driver_override,強制選擇某個 platform_driver。
然後比較: platform_device. name 和 和 platform_driver.id_table[i].name,
Platform_driver.id_table 是“platform_device_id”指標,表示該 drv 支援若干個 device,它裡面列出了各個 device 的{.name, .driver_data},其中的“name”表示該 drv 支援的裝置的名字,driver_data是些提供給該 device 的私有資料。
最後比較: platform_device.name 和platform_driver.driver.name, platform_driver.id_table 可能為空,這時可以根據 platform_driver.driver.name 來尋找同名的 platform_device。
2.3 函式呼叫關係
2.4 常用函式
這些函式可檢視核心原始碼:drivers/base/platform.c,根據函式名即可知道其含義。下面摘取常用的幾個函式。
註冊和反註冊:
platform_device_register/ platform_device_unregister
platform_driver_register/ platform_driver_unregister
platform_add_devices // 註冊多個 device
獲得資源:
2.5 如何寫程式
分配/ 設定/ 註冊 platform_device 結構體:
在裡面定義所用資源,指定裝置名字。
分配/ 設定/ 註冊 platform_driver 結構體:
在其中的 probe 函式裡,分配/設定/註冊 file_operations 結構體,並從 platform_device 中確實所用硬體資源。指定 platform_driver 的名字。