嵌入式Linux Platform驅(qū)動(dòng)模型測(cè)試方式
一、為什么要用 Platform 驅(qū)動(dòng)模型?
想象一下,你正在開發(fā)一個(gè)嵌入式系統(tǒng)(比如智能家居控制器)。系統(tǒng)里有很多外設(shè)(比如 LED 燈、溫度傳感器),它們直接集成在芯片上(SoC),不像 USB 或網(wǎng)卡那樣可以熱插拔。
這些設(shè)備的特點(diǎn)是:
- 1. 固定不變:寄存器地址、中斷號(hào)等資源不會(huì)改變。
- 2.需要初始化:必須明確配置(比如設(shè)置寄存器值)才能工作。
- 3.不能自動(dòng)檢測(cè):不像 USB 設(shè)備那樣插拔即用。
傳統(tǒng)方法的痛點(diǎn):
早期的驅(qū)動(dòng)開發(fā)方式是將硬件信息(比如寄存器地址)直接寫死在驅(qū)動(dòng)代碼中。比如:
#define LED_REGISTER_ADDR 0x80000000
這樣做的問題:
- 1.驅(qū)動(dòng)和硬件強(qiáng)耦合:換一塊板子(比如寄存器地址變了),驅(qū)動(dòng)就要重寫。
- 2.維護(hù)困難:同一驅(qū)動(dòng)需要為不同平臺(tái)維護(hù)多個(gè)版本。
- 3.編譯復(fù)雜:不同硬件需要不同的編譯配置。
Platform 模型的好處
Platform 驅(qū)動(dòng)模型通過 “分離設(shè)備描述和驅(qū)動(dòng)實(shí)現(xiàn)” 解決了這些問題。
簡(jiǎn)單來說就是:
- 1.硬件信息(設(shè)備):通過設(shè)備樹(Device Tree)或代碼單獨(dú)描述。
- 2.驅(qū)動(dòng)邏輯:只關(guān)注如何操作硬件,不關(guān)心硬件的具體地址。
- 3.動(dòng)態(tài)匹配:內(nèi)核自動(dòng)將驅(qū)動(dòng)和設(shè)備關(guān)聯(lián),無需硬編碼。
二、Platform 驅(qū)動(dòng)模型的三大核心組件
1.Platform 總線(虛擬總線)
1.作用:像“紅娘”一樣,把設(shè)備和驅(qū)動(dòng)匹配起來。
2.匹配規(guī)則:
- 通過設(shè)備名稱(
name)。 - 通過設(shè)備樹中的
compatible字段。 - 通過
id_table表(支持多個(gè)設(shè)備變體)。
2.Platform 設(shè)備(platform_device)
1.作用:描述硬件資源(寄存器地址、中斷號(hào)等)。
2.定義方式:現(xiàn)在主流使用設(shè)備樹,即在 .dts 文件中定義設(shè)備節(jié)點(diǎn),如
gpioled {//添加設(shè)備節(jié)點(diǎn)
#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ū)動(dòng)(platform_driver)
作用:實(shí)現(xiàn)設(shè)備的操作邏輯(初始化、讀寫等)。
核心函數(shù):
probe():設(shè)備匹配成功后調(diào)用,用于初始化硬件。remove():驅(qū)動(dòng)卸載時(shí)釋放資源。如下:
static int led_probe(struct platform_device *dev)//相當(dāng)于初始化函數(shù)
{
printk("led driver and device was matched!\r\n");
/* 1、設(shè)置設(shè)備號(hào) */
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、注冊(cè)設(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ū)動(dòng)的時(shí)候關(guān)閉LED */
gpio_free(leddev.led0); /* 釋放IO */
cdev_del(&leddev.cdev); /* 刪除cdev */
unregister_chrdev_region(leddev.devid, LEDDEV_CNT); /* 注銷設(shè)備號(hào) */
device_destroy(leddev.class, leddev.devid);
class_destroy(leddev.class);
return 0;
}三、Platform 驅(qū)動(dòng)的工作流程
1. 設(shè)備描述,即在設(shè)備樹中定義設(shè)備:

2.驅(qū)動(dòng)注冊(cè),驅(qū)動(dòng)代碼中定義 platform_driver,并注冊(cè)到內(nèi)核:

3.驅(qū)動(dòng)與設(shè)備匹配,即內(nèi)核啟動(dòng)時(shí),會(huì)掃描設(shè)備樹中的設(shè)備節(jié)點(diǎn),如果發(fā)現(xiàn)某個(gè)設(shè)備的 compatible 字段與某個(gè)驅(qū)動(dòng)的 of_match_table 匹配,就會(huì)調(diào)用驅(qū)動(dòng)的 probe() 函數(shù),完成初始化。如下為定義的匹配項(xiàng):

四、測(cè)試
1.將驅(qū)動(dòng)文件掛載到imx6ull設(shè)備中,

2. 加載驅(qū)動(dòng)后查看對(duì)應(yīng)的platfoam驅(qū)動(dòng),

3.點(diǎn)燈測(cè)試,

總結(jié)
| 概念 | 作用 |
| Platform 總線 | 負(fù)責(zé)匹配設(shè)備和驅(qū)動(dòng),像“紅娘”一樣連接兩者。 |
| Platform 設(shè)備 | 描述硬件資源(寄存器、中斷等),通常通過設(shè)備樹定義。 |
| Platform 驅(qū)動(dòng) | 實(shí)現(xiàn)設(shè)備操作邏輯,通過 probe() 初始化設(shè)備,通過 remove() 釋放資源。 |
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
通過 SSH 在遠(yuǎn)程 Linux 系統(tǒng)上運(yùn)行命令的方法
這篇文章主要介紹了通過 SSH 在遠(yuǎn)程 Linux 系統(tǒng)上運(yùn)行命令的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10
Linux(RedHat或CentOS)下實(shí)現(xiàn)開啟telnet服務(wù)方式
文章介紹了Telnet協(xié)議的功能及安全風(fēng)險(xiǎn),指出其明文傳輸導(dǎo)致安全隱患,現(xiàn)代系統(tǒng)多默認(rèn)禁用,詳細(xì)說明了開啟Telnet的步驟,包括安裝、配置yum源、啟動(dòng)服務(wù)及處理防火墻,同時(shí)區(qū)分不同系統(tǒng)版本的配置差異2025-07-07

