嵌入式Linux Platform驅(qū)動模型測試方式
一、為什么要用 Platform 驅(qū)動模型?
想象一下,你正在開發(fā)一個嵌入式系統(tǒng)(比如智能家居控制器)。系統(tǒng)里有很多外設(shè)(比如 LED 燈、溫度傳感器),它們直接集成在芯片上(SoC),不像 USB 或網(wǎng)卡那樣可以熱插拔。
這些設(shè)備的特點是:
- 1. 固定不變:寄存器地址、中斷號等資源不會改變。
- 2.需要初始化:必須明確配置(比如設(shè)置寄存器值)才能工作。
- 3.不能自動檢測:不像 USB 設(shè)備那樣插拔即用。
傳統(tǒng)方法的痛點:
早期的驅(qū)動開發(fā)方式是將硬件信息(比如寄存器地址)直接寫死在驅(qū)動代碼中。比如:
#define LED_REGISTER_ADDR 0x80000000
這樣做的問題:
- 1.驅(qū)動和硬件強耦合:換一塊板子(比如寄存器地址變了),驅(qū)動就要重寫。
- 2.維護(hù)困難:同一驅(qū)動需要為不同平臺維護(hù)多個版本。
- 3.編譯復(fù)雜:不同硬件需要不同的編譯配置。
Platform 模型的好處
Platform 驅(qū)動模型通過 “分離設(shè)備描述和驅(qū)動實現(xiàn)” 解決了這些問題。
簡單來說就是:
- 1.硬件信息(設(shè)備):通過設(shè)備樹(Device Tree)或代碼單獨描述。
- 2.驅(qū)動邏輯:只關(guān)注如何操作硬件,不關(guān)心硬件的具體地址。
- 3.動態(tài)匹配:內(nèi)核自動將驅(qū)動和設(shè)備關(guān)聯(lián),無需硬編碼。
二、Platform 驅(qū)動模型的三大核心組件
1.Platform 總線(虛擬總線)
1.作用:像“紅娘”一樣,把設(shè)備和驅(qū)動匹配起來。
2.匹配規(guī)則:
- 通過設(shè)備名稱(
name
)。 - 通過設(shè)備樹中的
compatible
字段。 - 通過
id_table
表(支持多個設(shè)備變體)。
2.Platform 設(shè)備(platform_device)
1.作用:描述硬件資源(寄存器地址、中斷號等)。
2.定義方式:現(xiàn)在主流使用設(shè)備樹,即在 .dts
文件中定義設(shè)備節(jié)點,如
gpioled {//添加設(shè)備節(jié)點 #address-cells = <1>; #size-cells = <1>; compatible = "atkalpha-gpioled"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_led>; led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; status = "okay"; };
3.Platform 驅(qū)動(platform_driver)
作用:實現(xiàn)設(shè)備的操作邏輯(初始化、讀寫等)。
核心函數(shù):
probe()
:設(shè)備匹配成功后調(diào)用,用于初始化硬件。remove()
:驅(qū)動卸載時釋放資源。如下:
static int led_probe(struct platform_device *dev)//相當(dāng)于初始化函數(shù) { printk("led driver and device was matched!\r\n"); /* 1、設(shè)置設(shè)備號 */ if (leddev.major) { leddev.devid = MKDEV(leddev.major, 0); register_chrdev_region(leddev.devid, LEDDEV_CNT, LEDDEV_NAME); } else { alloc_chrdev_region(&leddev.devid, 0, LEDDEV_CNT, LEDDEV_NAME); leddev.major = MAJOR(leddev.devid); } /* 2、注冊設(shè)備 */ cdev_init(&leddev.cdev, &led_fops); cdev_add(&leddev.cdev, leddev.devid, LEDDEV_CNT); /* 3、創(chuàng)建類 */ leddev.class = class_create(THIS_MODULE, LEDDEV_NAME); if (IS_ERR(leddev.class)) { return PTR_ERR(leddev.class); } /* 4、創(chuàng)建設(shè)備 */ leddev.device = device_create(leddev.class, NULL, leddev.devid, NULL, LEDDEV_NAME); if (IS_ERR(leddev.device)) { return PTR_ERR(leddev.device); } /* 5、初始化IO */ leddev.node = of_find_node_by_path("/gpioled"); if (leddev.node == NULL){ printk("gpioled node nost find!\r\n"); return -EINVAL; } leddev.led0 = of_get_named_gpio(leddev.node, "led-gpio", 0); if (leddev.led0 < 0) { printk("can't get led-gpio\r\n"); return -EINVAL; } gpio_request(leddev.led0, "led0"); gpio_direction_output(leddev.led0, 1); /* led0 IO設(shè)置為輸出,默認(rèn)高電平 */ return 0; } static int led_remove(struct platform_device *dev) { gpio_set_value(leddev.led0, 1); /* 卸載驅(qū)動的時候關(guān)閉LED */ gpio_free(leddev.led0); /* 釋放IO */ cdev_del(&leddev.cdev); /* 刪除cdev */ unregister_chrdev_region(leddev.devid, LEDDEV_CNT); /* 注銷設(shè)備號 */ device_destroy(leddev.class, leddev.devid); class_destroy(leddev.class); return 0; }
三、Platform 驅(qū)動的工作流程
1. 設(shè)備描述,即在設(shè)備樹中定義設(shè)備:
2.驅(qū)動注冊,驅(qū)動代碼中定義 platform_driver
,并注冊到內(nèi)核:
3.驅(qū)動與設(shè)備匹配,即內(nèi)核啟動時,會掃描設(shè)備樹中的設(shè)備節(jié)點,如果發(fā)現(xiàn)某個設(shè)備的 compatible
字段與某個驅(qū)動的 of_match_table
匹配,就會調(diào)用驅(qū)動的 probe()
函數(shù),完成初始化。如下為定義的匹配項:
四、測試
1.將驅(qū)動文件掛載到imx6ull設(shè)備中,
2. 加載驅(qū)動后查看對應(yīng)的platfoam驅(qū)動,
3.點燈測試,
總結(jié)
概念 | 作用 |
Platform 總線 | 負(fù)責(zé)匹配設(shè)備和驅(qū)動,像“紅娘”一樣連接兩者。 |
Platform 設(shè)備 | 描述硬件資源(寄存器、中斷等),通常通過設(shè)備樹定義。 |
Platform 驅(qū)動 | 實現(xiàn)設(shè)備操作邏輯,通過 probe() 初始化設(shè)備,通過 remove() 釋放資源。 |
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
CentOS 7下用firewall-cmd控制端口與端口轉(zhuǎn)發(fā)詳解
這篇文章主要給大家介紹了在CentOS 7下用firewall-cmd控制端口與端口轉(zhuǎn)發(fā)的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下來來一起看看吧。2017-05-05分享9個實戰(zhàn)及面試常用Linux Shell腳本編寫
這篇文章主要介紹了9個實戰(zhàn)及面試常用Shell腳本編寫,非常不錯,具有一定的收藏價值,需要的朋友可以參考下2018-10-10詳解Ubuntu16.04啟動器圖標(biāo)異常解決方法
本篇文章主要介紹了詳解Ubuntu16.04啟動器圖標(biāo)異常解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04詳解如何在Linux系統(tǒng)中更改文件和目錄的權(quán)限
在Linux系統(tǒng)中,文件和目錄權(quán)限是安全性和訪問控制的關(guān)鍵組成部分,正確設(shè)置文件和目錄的權(quán)限可以確保只有授權(quán)的用戶能夠讀取、寫入或執(zhí)行這些文件和目錄,本文將詳細(xì)介紹如何在Linux系統(tǒng)中更改文件和目錄的權(quán)限,需要的朋友可以參考下2023-12-12Linux 服務(wù)器同步 Rsync同步服務(wù)器文件
服務(wù)器之間常常要保持些文件或目錄的一致,比如一些大的軟件下載網(wǎng)站,它們通常使用多臺服 務(wù)器來提供下載服務(wù)。2009-08-08