设备树下的platform 驱动编写
目錄
- 設備樹下的platform 驅動簡介
- 硬件原理圖分析
- 實驗程序編寫
- 修改設備樹文件
- platform 驅動程序編寫
- 編寫測試APP
- 運行測試
- 編譯驅動程序和測試APP
- 運行測試
上一章我們詳細的講解了Linux 下的驅動分離與分層,以及總線、設備和驅動這樣的驅動框架。基于總線、設備和驅動這樣的驅動框架,Linux 內核提出來platform 這個虛擬總線,相應的也有platform 設備和platform 驅動。上一章我們講解了傳統的、未采用設備樹的platform 設備和驅動編寫方法。最新的Linux 內核已經支持了設備樹,因此在設備樹下如何編寫platform驅動就顯得尤為重要,本章我們就來學習一下如何在設備樹下編寫platform 驅動。
設備樹下的platform 驅動簡介
platform 驅動框架分為總線、設備和驅動,其中總線不需要我們這些驅動程序員去管理,這個是Linux 內核提供的,我們在編寫驅動的時候只要關注于設備和驅動的具體實現即可。在沒有設備樹的Linux 內核下,我們需要分別編寫并注冊platform_device 和platform_driver,分別代表設備和驅動。在使用設備樹的時候,設備的描述被放到了設備樹中,因此platform_device 就不需要我們去編寫了,我們只需要實現platform_driver 即可。在編寫基于設備樹的platform 驅動的時候我們需要注意一下幾點:
1、在設備樹中創建設備節點
毫無疑問,肯定要先在設備樹中創建設備節點來描述設備信息,重點是要設置好compatible屬性的值,因為platform 總線需要通過設備節點的compatible 屬性值來匹配驅動!這點要切記。
比如,我們可以編寫如下所示的設備節點來描述我們本章實驗要用到的LED 這個設備:
示例55.1.1 中的gpioled 節點其實就是45.4.1.2 小節中創建的gpioled 設備節點,我們可以直接拿過來用。注意第4 行的compatible 屬性值為“atkalpha-gpioled”,因此一會在編寫platform驅動的時候of_match_table 屬性表中要有“atkalpha-gpioled”。
2、編寫platform 驅動的時候要注意兼容屬性
上一章已經詳細的講解過了,在使用設備樹的時候platform 驅動會通過of_match_table 來保存兼容性值,也就是表明此驅動兼容哪些設備。所以,of_match_table 將會尤為重要,比如本例程的platform 驅動中platform_driver 就可以按照如下所示設置:
第1~4 行,of_device_id 表,也就是驅動的兼容表,是一個數組,每個數組元素為of_device_id類型。每個數組元素都是一個兼容屬性,表示兼容的設備,一個驅動可以跟多個設備匹配。這里我們僅僅匹配了一個設備,那就是55.1.1 中創建的gpioled 這個設備。第2 行的compatible 值為“atkalpha-gpioled”,驅動中的compatible 屬性和設備中的compatible 屬性相匹配,因此驅動中對應的probe 函數就會執行。注意第3 行是一個空元素,在編寫of_device_id 的時候最后一個元素一定要為空!
第6 行,通過MODULE_DEVICE_TABLE 聲明一下leds_of_match 這個設備匹配表。
第11 行,設置platform_driver 中的of_match_table 匹配表為上面創建的leds_of_match,至此我們就設置好了platform 驅動的匹配表了。
3、編寫platform 驅動
基于設備樹的platform 驅動和上一章無設備樹的platform 驅動基本一樣,都是當驅動和設備匹配成功以后就會執行probe 函數。我們需要在probe 函數里面執行字符設備驅動那一套,
當注銷驅動模塊的時候remove 函數就會執行,都是大同小異的。
硬件原理圖分析
本章實驗我們只使用到IMX6U-ALPHA 開發板上的LED 燈,因此實驗硬件原理圖參考8.3小節即可。
實驗程序編寫
本實驗對應的例程路徑為:開發板光盤-> 2、Linux 驅動例程-> 18_dtsplatform。
本章實驗我們編寫基于設備樹的platform 驅動,所以需要在設備樹中添加設備節點,然后我們只需要編寫platform 驅動即可。
修改設備樹文件
首先修改設備樹文件,加上我們需要的設備信息,本章我們就使用到一個LED 燈,因此可以直接使用45.4.1 小節編寫的gpioled 子節點即可,不需要再重復添加。
platform 驅動程序編寫
設備已經準備好了,接下來就要編寫相應的platform 驅動了,新建名為“18_dtsplatform”的文件夾,然后在18_dtsplatform 文件夾里面創建vscode 工程,工作區命名為“dtsplatform”。
新建名為leddriver.c 的驅動文件,在leddriver.c 中輸入如下所示內容:
第33~112 行,傳統的字符設備驅動,沒什么要說的。
第120~164 行,platform 驅動的probe 函數,當設備樹中的設備節點與驅動之間匹配成功以后此函數就會執行,原來在驅動加載函數里面做的工作現在全部放到probe 函數里面完成。
第171~180 行,remobe 函數,當卸載platform 驅動的時候此函數就會執行。在此函數里面釋放內存、注銷字符設備等,也就是將原來驅動卸載函數里面的工作全部都放到remove 函數中完成。
第183~186 行,匹配表,描述了此驅動都和什么樣的設備匹配,第184 行添加了一條值為"atkalpha-gpioled"的compatible 屬性值,當設備樹中某個設備節點的compatible 屬性值也為“atkalpha-gpioled”的時候就會與此驅動匹配。
第189~196 行,platform_driver 驅動結構體,191 行設置這個platform 驅動的名字為“imx6ul-led”,因此,當驅動加載成功以后就會在/sys/bus/platform/drivers/目錄下存在一個名為“imx6u-
led”的文件。第192 行設置of_match_table 為上面的led_of_match。
第203~206 行,驅動模塊加載函數,在此函數里面通過platform_driver_register 向Linux 內核注冊led_driver 驅動。
第213~216 行,驅動模塊卸載函數,在此函數里面通過platform_driver_unregister 從Linux內核卸載led_driver 驅動。
編寫測試APP
測試APP 就直接使用上一章54.4.2 小節編寫的ledApp.c 即可。
運行測試
編譯驅動程序和測試APP
1、編譯驅動程序
編寫Makefile 文件,本章實驗的Makefile 文件和第四十章實驗基本一樣,只是將obj-m 變量的值改為“leddriver.o”,Makefile 內容如下所示:
第4 行,設置obj-m 變量的值為“leddriver.o”。
輸入如下命令編譯出驅動模塊文件:
編譯成功以后就會生成一個名為“leddriver.o”的驅動模塊文件。
2、編譯測試APP
測試APP 直接使用上一章的ledApp 這個測試軟件即可。
運行測試
將上一小節編譯出來leddriver.ko 拷貝到rootfs/lib/modules/4.1.15 目錄中,重啟開發板,進入到目錄lib/modules/4.1.15 中,輸入如下命令加載leddriver.ko 這個驅動模塊。
depmod //第一次加載驅動的時候需要運行此命令 modprobe leddriver.ko //加載驅動模塊驅動模塊加載完成以后到/sys/bus/platform/drivers/目錄下查看驅動是否存在,我們在leddriver.c 中設置led_driver (platform_driver 類型)的name 字段為“imx6ul-led”,因此會在/sys/bus/platform/drivers/目錄下存在名為“imx6ul-led”這個文件,結果如圖55.4.2.1 所示:
同理,在/sys/bus/platform/devices/目錄下也存在led 的設備文件,也就是設備樹中gpioled 這個節點,如圖55.4.2.2 所示:
驅動和模塊都存在,當驅動和設備匹配成功以后就會輸出如圖55.4.2.3 所示一行語句:
驅動和設備匹配成功以后就可以測試LED 燈驅動了,輸入如下命令打開LED 燈:
./ledApp /dev/dtsplatled 1 //打開LED 燈在輸入如下命令關閉LED 燈:
./ledApp /dev/dtsplatled 0 //關閉LED 燈觀察一下LED 燈能否打開和關閉,如果可以的話就說明驅動工作正常,如果要卸載驅動的話輸入如下命令即可:
rmmod leddriver.ko總結
以上是生活随笔為你收集整理的设备树下的platform 驱动编写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库应用(MySQL客户端工具:Nav
- 下一篇: ios开发之.pch文件的使用