精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

實戰演練:設備樹(DTS)語法詳解 + LED控制實戰

開發 前端
在嵌入式系統的廣袤天地中,設備樹(Device Tree)宛如一座橋梁,橫跨在硬件與軟件之間,承擔著至關重要的溝通使命。

在嵌入式開發領域,設備樹(Device Tree)扮演著極為關鍵的角色。它如同一份精準的硬件說明書,讓操作系統能夠清晰識別并高效管理硬件資源。當我們著手為自定義硬件編寫設備樹時,就如同為新成員量身定制一套專屬 “檔案”,確保其能無縫融入系統 “大家庭”。

想象一下,你精心設計了一款獨特的硬件,滿心期待它在系統中發揮作用。但如果沒有正確編寫設備樹,操作系統很可能對其 “視而不見”,讓你的心血難以充分施展。那么,如何才能為自定義硬件編寫正確的設備樹呢?

接下來,我們將通過一系列實戰演練,帶你逐步攻克這一技術要點,從了解硬件配置的基礎信息,到精準修改設備樹源文件,再到生成可被系統讀取的二進制文件等,每一步都為你詳細拆解,助你在自定義硬件開發之路上穩步前行 。

一、設備樹初印象:為何而生?

在嵌入式系統的廣袤天地中,設備樹(Device Tree)宛如一座橋梁,橫跨在硬件與軟件之間,承擔著至關重要的溝通使命。在設備樹出現之前,嵌入式系統的開發可沒少讓開發者們頭疼。就拿 ARM 架構來說,不同開發板的硬件信息就像一團亂麻,緊緊地與內核代碼交織在一起。想象一下,每更換一次開發板,那密密麻麻的內核代碼就得大改特改,移植工作不僅繁瑣,還極易出錯,維護成本更是高得嚇人。

為了化解這些難題,設備樹應運而生。它最早在 PowerPC 架構中嶄露頭角,隨后便在 ARM、MIPS 等多種架構中廣泛應用,迅速成為嵌入式開發的得力助手。設備樹的核心使命,就是將硬件描述從內核代碼中剝離出來,實現兩者的解耦。如此一來,內核變得更加通用,開發板相關的特定信息則由設備樹文件專門負責描述。當我們要將內核移植到新的開發板時,只需對設備樹文件進行修改,這極大地降低了移植的難度和工作量,就像是給復雜的開發工作找到了一條捷徑。

舉個例子,在一個基于 ARM 架構的智能家居控制系統開發中,以往若要適配不同廠家生產的開發板,每個開發板都有獨特的硬件配置,如不同的 GPIO 引腳分配、外設接口等。在沒有設備樹時,針對每一款開發板,內核代碼中都要硬編碼大量的硬件相關信息,這導致內核代碼臃腫不堪,且維護極為困難。一旦硬件稍有變動,例如更換了一個不同型號的傳感器,與之相連的引腳發生變化,就需要在冗長的內核代碼中四處尋找并修改相關配置,不僅容易遺漏,而且修改過程繁瑣,極易引入新的錯誤。

有了設備樹后,情況就大為不同。硬件相關信息被清晰地描述在設備樹文件中。若要適配新的開發板,或者更改硬件配置,只需在設備樹文件中相應節點處修改屬性值即可。比如,要更改傳感器連接的 GPIO 引腳,只需在設備樹中找到對應的傳感器節點,修改其 GPIO 屬性值,而無需對內核代碼進行大規模改動。這使得開發過程更加靈活高效,同時也提高了代碼的可維護性和可移植性 。

1.1設備樹在ARM架構的引入

在之前使用 S3C2440 開發板移植 Linux 3.4.2 內核時,修改了很多關于 c 文件去適配開發板,和開發板相關的文件放在arch/arm/mxch-xxx目錄下,因此 linux 內核 arm 架構下添加了很多開發板的適配文件:

圖片圖片

這些 c 文件僅僅用來適配某款開發板,對于 Linux 內核來說并沒有提交什么新功能,但是每適配一款新的開發板就需要一堆文件,導致 Linux 內核越來越臃腫:

圖片圖片

終于 Linus 忍不住天天 merge 這些鬼東西,向 arm 社區發出了一封郵件,第一句話就足矣表現不滿:"This whole ARM thing is a f*cking pain in the ass"。

因此,Arm 社區開始引入之前 powerPC 架構就采用的設備樹,將描述這些板級信息的文件與 Linux 內核代碼分離,Linux 4.x 版本幾乎都支持設備樹,所有開發板的設備樹文件統一放在arch/arm/boot/dts目錄中。

1.2什么是設備樹

設備樹全稱 Device Tree,是一種數據結構,用來描述板級設備信息,比如 CPU 數量、外設基地址、總線設備等,如圖:

圖片圖片

DTS、DTB、DTC三種文件的區別

  • DTS 是設備樹源碼文件
  • DTB 是將DTS 編譯以后得到的二進制文件
  • DTC工具是將dts文件變成編譯成dtb的工具,就像.c文件變成成.o需要用到gcc編譯器一樣。

1.3 設備樹編譯

①簡單粗暴,編譯內核

make

②編譯全部設備樹文件

make dtbs

③編譯指定的設備樹文件

make <xxx.dtb>

二、設備樹語法

2.1設備樹相關術語全解析

在深入探索設備樹的世界之前,先來認識一下那些頻繁出現的術語,它們就像是開啟設備樹大門的鑰匙。

DT(Device Tree,設備樹):這是一種用于描述計算機系統硬件布局的數據結構,它將系統中的各類硬件組件及其連接關系,以層次化的樹狀結構呈現出來??梢园阉胂蟪墒怯布?“戶口簿”,詳細記錄著每個硬件設備的 “身份信息” 以及它們之間的 “親屬關系” ,為內核提供了清晰的硬件信息,讓內核能夠有條不紊地初始化和操作硬件設備。

FDT(Flattened Device Tree,扁平設備樹):FDT 是設備樹的二進制表示形式,就像是設備樹的 “壓縮包”。它由設備樹編譯器(dtc)精心打造而成,是 dts 文件編譯后的產物。這種緊湊的存儲方式,使其在系統啟動時能夠快速加載和解析,大大提高了系統啟動的效率 ,就好比將一本厚厚的書壓縮成了一個小巧的文件,攜帶和讀取都更加便捷。

dts(Device Tree Source,設備樹源文件):dts 文件是設備樹的源文件,以通俗易懂的文本格式編寫,是硬件開發人員或系統集成商施展拳腳的舞臺。他們通過編寫 dts 文件,詳細描述系統中的硬件設備及其屬性,就像建筑師繪制建筑藍圖一樣,為后續的硬件實現和系統開發奠定基礎。這個文件就像是設備樹的 “初稿”,記錄著最原始的硬件描述信息。

dtsi(Device Tree Source Include,設備樹源包含文件):dtsi 文件類似于編程中的頭文件,是設備樹源文件的得力助手。它通常包含一些被多個 dts 文件共享的硬件描述,通過 #include 指令巧妙地融入到具體的 dts 文件中。這樣一來,不僅避免了重復代碼,還讓硬件描述的管理和維護變得更加輕松,就像是一個公共的資源庫,各個 dts 文件都可以按需取用其中的內容 。

dtb(Device Tree Blob,設備樹二進制文件):dtb 文件是 dts 文件經過編譯后生成的二進制文件,包含了設備樹的扁平表示形式(FDT)。在系統啟動的關鍵時刻,引導加載程序(如 U-Boot)會將 dtb 文件從存儲設備中加載到內存,并恭敬地傳遞給操作系統內核。內核則依據 dtb 文件中描述的信息,對硬件進行初始化操作,它就像是一份被加密后的硬件說明書,只有內核能夠讀懂并依據它來配置硬件 。

dtc(Device Tree Compiler,設備樹編譯器):dtc 是設備樹世界中的 “翻譯官”,它肩負著將 dts 文件編譯為 dtb 文件的重任。不僅如此,在調試和修改設備樹時,它還能將 dtb 文件反編譯為 dts 文件,為開發者提供了極大的便利。就好比一個語言專家,能夠在不同格式的設備樹文件之間自由轉換 。

這些術語相互協作,共同構建起設備樹的生態系統。dts 和 dtsi 文件是設備樹的源代碼基礎,dtc 編譯器將它們轉換為內核能夠識別的 dtb 文件,而 FDT 則是 dtb 文件內部的一種高效存儲結構,DT 則是整個硬件描述概念的統稱 。

2.2設備樹源碼藏身何處

在 Linux 內核源碼的龐大體系中,設備樹源碼有著自己專屬的 “棲息地”。對于 32 位系統而言,設備樹源碼通常存放在 “源碼 /arch/arm/boot/dts” 目錄下;而在 64 位系統中,它們則位于 “源碼 /arch/arm64/boot/dts” 目錄 。

在這些目錄中,你能找到眾多以.dts 和.dtsi 為擴展名的文件,它們就像是隱藏在代碼海洋中的寶藏,記錄著硬件設備的詳細信息 。不同架構的設備樹文件存放位置和命名規則可能會略有差異,所以在探索時,一定要查閱對應架構的文檔或源碼,這樣才能準確找到所需的設備樹文件 。

2.3DTC 工具的神奇用法

DTC 工具作為設備樹編譯和反編譯的利器,掌握它的使用方法至關重要。下面就來看看如何使用 DTC 工具進行設備樹的編譯和反編譯操作 。

(1)編譯設備樹

基本的編譯命令格式為 “dtc -I dts -O dtb -o output_file.dtb input_file.dts”。其中,“dtc” 是調用設備樹編譯器;“-I dts” 明確指定輸入文件的格式為設備樹源文件(DTS),就像是告訴編譯器要處理的是哪種類型的 “原材料”;“-O dtb” 指定輸出文件的格式為設備樹二進制文件(DTB),也就是確定了 “成品” 的格式;“-o output_file.dtb” 則指定了輸出文件的名稱,讓編譯器知道要把生成的文件保存成什么名字;“input_file.dts” 自然就是指定輸入的設備樹源文件了 。

例如,我們有一個名為 “my_device.dts” 的設備樹源文件,想要將其編譯成二進制文件 “my_device.dtb”,就可以在命令行中輸入 “dtc -I dts -O dtb -o my_device.dtb my_device.dts”,按下回車鍵,DTC 工具就會迅速行動,將 dts 文件編譯成 dtb 文件 。

(2)反編譯設備樹

反編譯的命令格式為 “dtc -I dtb -O dts -o example.dts example.dtb”。這里的參數含義與編譯時類似,只是輸入和輸出的格式進行了互換?!?I dtb” 表示輸入文件是設備樹二進制文件(DTB),“-O dts” 表示輸出文件為設備樹源文件(DTS) 。

假設我們有一個 “example.dtb” 的二進制文件,想要查看其原始的設備樹描述內容,就可以使用 “dtc -I dtb -O dts -o example.dts example.dtb” 命令,將 dtb 文件反編譯成 dts 文件,方便我們進行查看和修改 。

在實際操作過程中,還可能會用到其他一些參數。比如,“-q” 參數可以讓編譯過程更加安靜,減少不必要的提示信息;“-i” 參數可以添加搜索包含文件的路徑,方便在編譯時找到所需的 dtsi 文件等 。掌握這些參數的用法,能夠讓我們更加靈活地使用 DTC 工具,應對各種設備樹處理的需求 。

三、深入設備樹語法殿堂

3.1節點:設備樹的基石

節點是設備樹的基本組成單元,就像是樹狀結構中的一個個 “樹枝分叉點” ,每個節點都代表著一個硬件設備或組件。節點的命名遵循特定規則,通常以 “node-name@unit-address” 的形式出現 。其中,“node-name” 是節點的名稱,一般由字母、數字和下劃線組成,用來描述節點所代表的設備類型或功能,如 “uart” 代表串口設備,“i2c” 代表 I2C 總線設備等 。

“unit-address” 則是設備的單元地址,通常表示設備在內存空間或總線上的地址,像 “0x10000000” 這樣的十六進制數,它與設備的 “reg” 屬性密切相關 。若節點沒有地址相關信息,“@unit-address” 部分可以省略 。

每個節點內部可以包含多個屬性和子節點。屬性以鍵值對的形式存在,用于描述節點的各種特性;子節點則進一步細化硬件設備的層次結構 。例如,在描述一個 SPI 控制器時,可能會有如下節點:

spi@12340000 {
    compatible = "fsl,imx6ul-spi";
    reg = <0x12340000 0x1000>;
    interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
    #address-cells = <1>;
    #size-cells = <0>;

    spi_device: spi@0 {
        compatible = "my_spi_device";
        reg = <0>;
        spi-max-frequency = <5000000>;
    };
};

在這個例子中,“spi@12340000” 是 SPI 控制器節點,包含了描述其兼容性、地址、中斷等屬性 。而 “spi_device: spi@0” 則是 SPI 控制器下的一個子節點,表示連接在該 SPI 總線上的一個設備,有自己的兼容性、設備地址和最大工作頻率等屬性 。

3.2屬性:描述設備的關鍵

屬性是節點的重要組成部分,以 “name = value” 的形式存在,用于詳細描述節點所代表設備的各種特性 。屬性的值可以是多種數據類型,常見的有以下幾種:

  1. 32 位無符號整數:用尖括號 “<>” 括起來,如 “interrupts = <17 0xc>”,表示該設備的中斷號為 17,觸發方式為 0xc(具體含義根據中斷控制器的定義) 。
  2. 字符串:用雙引號 “""” 括起來,如 “compatible ="arm,cortex-a7"”,“compatible” 屬性用于驅動與設備的匹配,這里表示該設備與 “arm,cortex-a7” 類型兼容 。
  3. 字節數組:用方括號 “[]” 括起來,每個字節用兩個十六進制數表示,如 “local-mac-address = [00 00 12 34 56 78]”,用于表示設備的本地 MAC 地址 。
  4. 復合類型:可以是多種值的組合,用逗號 “,” 隔開,如 “example = <0xf00f0000 19>, "a strange property format"” 。

在眾多屬性中,“compatible” 和 “reg” 屬性尤為常用 ?!癱ompatible” 屬性就像是設備的 “身份證”,用于設備與驅動程序的匹配 。內核在尋找設備驅動時,會根據設備節點的 “compatible” 屬性值,在驅動列表中查找與之匹配的驅動 。例如,“compatible = "fsl,imx6ul-spi", "spi-gpio"”,表示該設備首先嘗試匹配 “fsl,imx6ul-spi” 驅動,若找不到,則嘗試匹配 “spi-gpio” 驅動 。

“reg” 屬性用于描述設備的寄存器地址范圍,其值是一系列的 “address size” 對 ?!癮ddress” 表示設備寄存器的起始地址,“size” 表示地址范圍的大小 。這兩個值的表示方式由其父節點的 “#address-cells” 和 “#size-cells” 屬性決定 。比如,在下面的例子中:

soc {
    #address-cells = <1>;
    #size-cells = <1>;

    spi@12340000 {
        reg = <0x12340000 0x1000>;
        ...
    };
};

由于 “soc” 節點的 “#address-cells = <1>” 和 “#size-cells = <1>”,所以 “spi@12340000” 節點的 “reg” 屬性中,“0x12340000” 用 1 個 32 位整數表示起始地址,“0x1000” 用 1 個 32 位整數表示地址范圍大小 。

3.3包含文件:代碼復用的利器

在設備樹開發中,為了提高代碼的復用性和可維護性,常常會使用包含文件(dtsi) 。dtsi 文件類似于 C 語言中的頭文件,用于存放被多個 dts 文件共享的設備樹描述 。通過使用包含文件,可以避免在多個 dts 文件中重復編寫相同的硬件描述代碼 。

在 dts 文件中,可以使用 “#include” 指令來引用 dtsi 文件 。例如:

#include "common.dtsi"

這樣,“common.dtsi” 文件中的內容就會被包含到當前 dts 文件中 。除了 dtsi 文件,設備樹源文件也可以包含標準的 C 頭文件(.h) 。這在需要使用一些宏定義或常量時非常方便 。例如,在 dts 文件中可能會包含如下頭文件:

#include <dt-bindings/gpio/gpio.h>

通過包含這個頭文件,可以在設備樹中使用其中定義的 GPIO 相關宏,如 “GPIO_ACTIVE_HIGH”“GPIO_ACTIVE_LOW” 等 。這樣不僅提高了代碼的可讀性,還減少了人為錯誤 。

3.4節點路徑:精準定位節點

在設備樹這個龐大的 “家族樹” 中,每個節點都有其唯一的路徑,就像每個人在家族族譜中都有獨特的位置標識一樣 。節點路徑是從根節點開始,通過各級子節點的名稱和地址,以 “/” 分隔組成的 。例如,對于前面提到的 SPI 控制器節點,其路徑為 “/soc/spi@12340000” 。

通過節點路徑,我們可以在設備樹中精準地訪問特定節點 。在 Linux 內核中,提供了一系列函數來通過節點路徑查找節點 。例如,“of_find_node_by_path (const char *path)” 函數,它接收一個節點路徑作為參數,返回對應節點的指針 。假設我們要獲取 SPI 控制器節點的信息,就可以使用如下代碼:

#include <linux/of.h>
#include <linux/device.h>

struct device_node *spi_node;
spi_node = of_find_node_by_path("/soc/spi@12340000");
if (spi_node) {
    // 在這里可以對找到的節點進行操作,如獲取屬性等
    of_node_put(spi_node);
}

在實際應用中,節點路徑常用于設備驅動開發 。驅動程序需要根據設備樹中節點的信息來初始化和操作硬件設備,通過節點路徑可以快速準確地找到對應的設備節點,從而獲取設備的屬性和配置信息 。

3.5別名:便捷訪問節點

別名就像是設備樹節點的 “昵稱”,為了更方便地訪問設備樹中的節點而存在 。通過定義別名,可以使用一個簡短的名稱來代替冗長的節點路徑 。別名的定義通常在設備樹的根節點下,使用 “aliases” 屬性 。例如:

aliases {
    spi0 = &spi@12340000;
    uart1 = &uart@101f0000;
};

在這個例子中,為 “spi@12340000” 節點定義了別名 “spi0”,為 “uart@101f0000” 節點定義了別名 “uart1” 。這樣,在設備樹的其他部分,或者在驅動程序中,就可以使用這些別名來代替完整的節點路徑 。例如,在驅動程序中,可以使用 “of_find_node_by_phandle (of_parse_phandle (aliases, "spi0", 0))” 來通過別名 “spi0” 找到對應的 SPI 控制器節點 。

別名的使用不僅提高了設備樹的可讀性,還使代碼更加簡潔和易于維護 。特別是在大型設備樹中,當需要頻繁訪問某些節點時,使用別名可以大大減少代碼中冗長路徑的出現,降低出錯的概率 。

3.6復合節點與定義引用:復雜關系的處理

在描述復雜的硬件設備關系時,復合節點和定義引用發揮著重要作用 。復合節點是指一個節點可以包含多個子節點,這些子節點共同描述一個復雜的硬件設備或功能 。例如,在描述一個包含多個功能模塊的芯片時,可能會有如下復合節點:

chip@10000000 {
    compatible = "my_chip";
    reg = <0x10000000 0x10000>;

    module1: submodule@1000 {
        compatible = "module1_type";
        reg = <0x1000 0x100>;
    };

    module2: submodule@2000 {
        compatible = "module2_type";
        reg = <0x2000 0x200>;
    };
};

在這個例子中,“chip@10000000” 是一個復合節點,包含了 “module1” 和 “module2” 兩個子節點,分別描述芯片中的兩個不同功能模塊 。

定義引用則是通過 “&label” 的方式來引用其他節點 。例如,在前面的例子中,如果有另一個節點需要使用 “module1” 節點的信息,可以這樣引用:

other_node {
    depends_on = <&module1>;
    // 其他屬性和子節點
};

這里的 “depends_on = <&module1>” 表示 “other_node” 節點依賴于 “module1” 節點 。通過這種方式,可以清晰地表達硬件設備之間的依賴關系 。

在實際應用中,復合節點和定義引用常用于描述復雜的硬件系統,如片上系統(SoC) 。SoC 通常包含多個處理器核心、各種外設控制器等,通過復合節點和定義引用,可以準確地描述這些組件之間的層次結構和相互關系,為內核提供完整的硬件信息 。

四、實戰:設備樹實例深度剖析

4.1GPIO設備樹實例詳解

以某款基于 ARM 架構的開發板為例,其設備樹中 GPIO 設備樹節點如下:

gpio0: gpio@10000000 {
    compatible = "fsl,imx6ul-gpio", "gpio-generic";
    reg = <0x10000000 0x1000>;
    interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
    gpio-controller;
    #gpio-cells = <2>;
};

在這個節點中,“compatible” 屬性表明該 GPIO 控制器與 “fsl,imx6ul-gpio” 和 “gpio-generic” 兼容,這使得內核能夠準確找到與之匹配的驅動程序 ?!皉eg” 屬性指定了 GPIO 控制器的寄存器地址范圍,起始地址為 0x10000000,大小為 0x1000 字節 ?!癷nterrupts” 屬性描述了 GPIO 控制器的中斷信息,使用 GIC_SPI 類型的中斷,中斷號為 66,觸發方式為高電平觸發 。

“gpio-controller” 屬性標識該節點為 GPIO 控制器 ?!?gpio-cells = <2>” 則表示在引用該 GPIO 控制器時,需要兩個 32 位的參數 。第一個參數表示 GPIO 的編號,第二個參數表示 GPIO 的觸發類型 。例如,在其他節點中引用該 GPIO 控制器的某個引腳時,可能會這樣寫:

my_device {
    gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
    ...
};

這里表示使用 “gpio0” 控制器的第 10 號引腳,觸發類型為高電平有效 。這種屬性設置方式,為系統中其他設備使用 GPIO 提供了清晰的規范和接口 。

4.2LED設備樹實例全解析

假設我們要在開發板上實現一個 LED 驅動,首先在設備樹中定義 LED 節點:

leds {
    compatible = "gpio-leds";
    pinctrl-names = "default";
    pinctrl-0 = <&led_pins>;

    led_red: red_led {
        label = "red_led";
        gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
        default-state = "off";
    };
};

pinctrl: pinctrl@10000400 {
    compatible = "fsl,imx6ul-pinctrl";
    reg = <0x10000400 0x1000>;

    led_pins: ledgrp {
        fsl,pins = <
            MX6UL_PAD_GPIO1_IO18__GPIO1_IO18 0x10b0
        >;
    };
};

在這個設備樹實例中,“leds” 節點的 “compatible = "gpio-leds"” 屬性表明這是一個基于 GPIO 的 LED 設備 ?!皃inctrl-names” 和 “pinctrl-0” 屬性用于引腳控制,通過引用 “led_pins” 節點來配置 LED 所使用的引腳 。

“led_red” 子節點定義了一個紅色 LED,“label” 屬性為其命名,“gpios” 屬性指定該 LED 連接到 “gpio1” 控制器的 18 號引腳,且為低電平有效 ?!癲efault-state = "off"” 表示 LED 默認處于熄滅狀態 。

在驅動開發中,內核驅動會根據 “compatible” 屬性找到對應的 LED 驅動程序 。在驅動的 probe 函數中,通過設備樹 API 函數來獲取設備樹節點信息 。例如,使用 “of_find_node_by_path” 函數找到 “leds” 節點,再通過 “of_get_child_by_name” 函數獲取 “led_red” 子節點 。

然后,利用 “of_property_read_u32_array” 函數讀取 “gpios” 屬性的值,從而獲取 LED 所連接的 GPIO 引腳信息 。最后,根據這些信息進行 GPIO 的初始化和 LED 的控制操作 。

4.3自定義設備樹節點與驅動匹配實例

假設我們要添加一個自定義的溫度傳感器設備,首先在設備樹中創建自定義節點:

temperature_sensor: sensor@1234 {
    compatible = "mycompany,temperature-sensor";
    reg = <0x1234 0x100>;
    sensor_type = "temperature";
    sampling_rate = <100>;
};

這個自定義節點 “temperature_sensor” 的 “compatible” 屬性設置為 “mycompany,temperature-sensor”,用于與驅動程序進行匹配 ?!皉eg” 屬性指定了傳感器的寄存器地址范圍 。“sensor_type” 和 “sampling_rate” 是自定義屬性,分別表示傳感器類型和采樣率 。

接下來編寫對應的內核驅動:

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>

static int my_sensor_probe(struct platform_device *pdev) {
    struct device_node *np = pdev->dev.of_node;
    u32 reg_val, sampling_rate;
    const char *sensor_type;

    if (!np)
        return -EINVAL;

    // 讀取reg屬性
    if (of_property_read_u32(np, "reg", ?_val) != 0) {
        dev_err(&pdev->dev, "Failed to read reg property\n");
        return -EINVAL;
    }

    // 讀取sensor_type屬性
    if (of_property_read_string(np, "sensor_type", &sensor_type) != 0) {
        dev_err(&pdev->dev, "Failed to read sensor_type property\n");
        return -EINVAL;
    }

    // 讀取sampling_rate屬性
    if (of_property_read_u32(np, "sampling_rate", &sampling_rate) != 0) {
        dev_err(&pdev->dev, "Failed to read sampling_rate property\n");
        return -EINVAL;
    }

    // 這里可以根據讀取到的屬性進行傳感器的初始化和操作
    dev_info(&pdev->dev, "Sensor initialized: reg = 0x%x, type = %s, sampling_rate = %d\n", reg_val, sensor_type, sampling_rate);

    return 0;
}

static int my_sensor_remove(struct platform_device *pdev) {
    // 清理操作
    return 0;
}

static const struct of_device_id my_sensor_of_match[] = {
    {.compatible = "mycompany,temperature-sensor"},
    {},
};
MODULE_DEVICE_TABLE(of, my_sensor_of_match);

static struct platform_driver my_sensor_driver = {
   .probe = my_sensor_probe,
   .remove = my_sensor_remove,
   .driver = {
       .name = "mycompany-temperature-sensor-driver",
       .of_match_table = my_sensor_of_match,
    },
};

module_platform_driver(my_sensor_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Custom Temperature Sensor Driver");

在這個驅動程序中,“my_sensor_of_match” 數組用于匹配設備樹中自定義節點的 “compatible” 屬性 。“my_sensor_probe” 函數在設備探測時被調用,通過設備樹 API 函數讀取設備樹節點的屬性信息,并進行相應的初始化操作 。這樣,通過 “compatible” 屬性,設備樹中的自定義節點與內核驅動成功匹配,驅動能夠正確解析設備樹屬性并對設備進行控制 。

責任編輯:武曉燕 來源: 深度Linux
相關推薦

2022-12-21 14:39:35

機器學習案發決策樹

2024-08-09 10:15:34

2009-09-18 14:31:33

CLR觸發器

2024-10-29 11:54:25

2022-08-25 09:00:00

Python編程語言開源庫

2012-11-09 09:35:18

Win 8

2024-08-05 09:31:00

MySQLDTS數據

2025-06-26 04:00:00

Spring數據綁定技術

2024-08-07 08:32:30

2010-05-26 18:16:31

MySQL數據庫安裝

2024-07-17 08:17:20

2024-11-22 09:21:18

WinForm

2025-11-17 00:00:55

2023-02-10 14:54:20

編譯工具cmake

2010-01-21 11:51:11

2017-04-26 08:51:36

MongoDB集群實戰

2023-11-07 10:22:26

自動駕駛技術

2024-07-15 09:13:48

2017-11-23 15:24:35

Python速覽實戰

2024-05-20 08:31:33

檢索增強生成LLM大型語言模型
點贊
收藏

51CTO技術棧公眾號

亚洲丁香日韩| 理论不卡电影大全神| 久久精品国产精品亚洲红杏| 久久视频在线观看免费| 午夜影院免费版| 欧美高清另类hdvideosexjaⅴ| 懂色av噜噜一区二区三区av | 秋霞午夜在线观看| 国产成人啪免费观看软件| 97成人超碰免| 国产99在线 | 亚洲| 国产视频91在线| 精品999视频| 久久精品久久99精品久久| 欧美国产日本在线| 东方伊人免费在线观看| 97se亚洲国产一区二区三区| 欧美日韩一区二区在线| 7777在线视频| 欧美成熟毛茸茸| 国产精品一区在线观看乱码 | 激情综合网五月天| 欧美系列电影免费观看| 欧美不卡在线视频| 999精品视频在线| 日本电影在线观看| 国产精品久久久久久久久快鸭| 国产精品一区二| 国产一区二区三区成人| 久久婷婷影院| 欧美国产极速在线| 伊人在线视频观看| 精品理论电影| 日韩成人网免费视频| 亚洲综合在线一区二区| 成人自拍视频网| 精品久久久在线观看| 麻豆传媒网站在线观看| 五月婷婷在线观看| 日本一区二区高清| 久久国产精品一区二区三区四区| 国内精品久久久久久久久久久| 日韩av电影天堂| 日本成熟性欧美| 日韩av电影网| 亚洲国产另类久久久精品极度| 人人妻人人澡人人爽久久av| 国产一区91精品张津瑜| 国产欧美精品一区二区三区-老狼| 好吊妞视频一区二区三区| 韩国欧美一区| 欧美老少做受xxxx高潮| 国产美女高潮视频| 欧美精选一区二区三区| 亚洲午夜精品久久久久久久久久久久 | 精品国产一区二区三| 亚洲av无码一区二区三区dv| 狠狠久久亚洲欧美| 91精品久久久久久久久久久久久久 | 伊人久久大香线蕉综合网站| 日韩av网站电影| 久久久午夜精品福利内容| 一区二区三区国产好| 日韩欧美电影一区| japan高清日本乱xxxxx| 嫩呦国产一区二区三区av| 91精品国产品国语在线不卡| 8x8x成人免费视频| 国产精品亚洲一区二区在线观看 | 欧美激情国产精品日韩| 欧美aa视频| 色噜噜狠狠成人网p站| 人妻精品无码一区二区三区 | 97精品国产一区二区三区| 一区二区三区无码高清视频| 精品人妻一区二区三区蜜桃视频| 欧美极品在线观看| 少妇高潮久久77777| 国产馆在线观看| 香蕉视频官网在线观看日本一区二区| 久久精品国产免费观看| 放荡的美妇在线播放| 欧美日本中文| 777精品视频| 蜜臀尤物一区二区三区直播| 免费看日韩精品| 91欧美视频网站| 蜜臀久久99精品久久久| 972aa.com艺术欧美| 日韩精彩视频| bt在线麻豆视频| 性做久久久久久| 日本精品一区二区三区四区| 久久天天久久| 精品欧美久久久| 欧美做受xxxxxⅹ性视频| 欧美日韩在线网站| 日韩中文字幕在线| 国产乡下妇女做爰| 男人的j进女人的j一区| 99re视频| 日产精品久久久久久久性色| 国产精品二区一区二区aⅴ污介绍| 日本丰满大乳奶| 亚洲天堂手机| 91精品欧美综合在线观看最新| 97人妻精品一区二区三区免费| 九九在线高清精品视频| 精品少妇v888av| 青青视频在线免费观看| 国产精品系列在线播放| 国产精品10p综合二区| 精品一二三区视频| 亚洲线精品一区二区三区八戒| 国产一级片黄色| 在这里有精品| 色综合影院在线| 1级黄色大片儿| 精品一区二区免费| 久久久com| 直接在线观看的三级网址| 欧美午夜视频一区二区| www.国产福利| 激情综合网站| 97热精品视频官网| 精品国产av一区二区| 国产欧美一区二区精品性色超碰| 国产成a人亚洲精v品在线观看| 日本一区二区电影| 日韩精品中文字幕在线播放| 黄色一级片中国| 日韩黄色免费网站| 精品中文字幕人| 任你弄在线视频免费观看| 欧美日本高清视频在线观看| 91中文字幕永久在线| 欧美成人首页| 国产日韩精品一区二区| 可以直接在线观看的av| 精品日本美女福利在线观看| 69久久精品无码一区二区| 大胆日韩av| 国产91色在线免费| 四虎影视2018在线播放alocalhost| 亚洲男人的天堂av| 日本不卡一区二区在线观看| 欧美手机在线| 国产成人精品av在线| 亚洲av成人精品一区二区三区在线播放| 亚洲欧美色一区| 中文字幕 欧美日韩| 日韩欧美一区二区三区在线视频| 欧美在线国产精品| 深夜福利视频一区| 欧美性色视频在线| 一卡二卡三卡四卡| 久久深夜福利| 一区二区三区日韩| 日韩网站在线免费观看| 都市激情亚洲| 午夜欧美大片免费观看| 欧美性猛交 xxxx| 亚洲夂夂婷婷色拍ww47| 少妇极品熟妇人妻无码| 欧美日韩影院| 国产成人免费观看| 欧美激情网站| 亚洲男人天天操| 欧美videossex极品| 久久精品亚洲乱码伦伦中文| caopor在线视频| 精品国产乱码久久久| 国产精品欧美激情| 日本三级视频在线播放| 欧美一区二区三区系列电影| 在线观看美女av| 国产白丝网站精品污在线入口| 久久久久99精品成人片| 全球av集中精品导航福利| 欧洲一区二区视频| 97电影在线观看| 欧美一级日韩不卡播放免费| 精品视频久久久久| www日韩大片| 色片在线免费观看| 自拍视频亚洲| 极品校花啪啪激情久久| 久久99久久99精品免观看软件| 日韩在线欧美在线| 精品国精品国产自在久不卡| 婷婷久久综合九色综合伊人色| 中文字幕免费高清| 国产成人自拍网| 91猫先生在线| 国产国产精品| 精品产品国产在线不卡| 成人在线视频免费| 欧美精品久久一区二区| 欧美色综合一区二区三区| 欧美日韩不卡一区二区| 国产精品自拍视频一区| 国产欧美一区二区三区在线老狼| 欧美日韩理论片| 亚洲中午字幕| 日韩不卡视频一区二区| 亚洲精品国产setv| 亚洲最大成人在线| 免费日韩电影| 色综合天天综合网国产成人网 | 日韩黄色高清视频| 中文字幕一区二区三区免费看| 亚洲激情自拍视频| 蜜桃av免费看| 成人丝袜视频网| 性生活免费在线观看| 在线欧美福利| 国产精品无码乱伦| 九九综合在线| 国产精品久久久久久免费观看 | 一区二区三区国产盗摄| 涩涩涩999| 欧美亚洲色图校园春色| 国产专区欧美专区| 精品成人免费一区二区在线播放| 欧美成人精品激情在线观看| 成人精品一区二区三区校园激情| 精品久久久久久无| 国产精品一二三四五区| 欧美在线制服丝袜| 国产成人无码精品亚洲| 一区二区三区在线视频观看| 欧美人与禽zoz0善交| 久久先锋资源网| 国产伦精品一区三区精东| 国产精品一色哟哟哟| 日韩在线一区视频| 美腿丝袜亚洲综合| 自拍偷拍 国产| 男人的天堂亚洲| 日韩国产欧美亚洲| 在线日韩电影| 欧美高清中文字幕| 亚洲精品tv久久久久久久久久| 亚洲福利av在线| 九九热线有精品视频99| 蜜桃传媒视频麻豆第一区免费观看 | 天天躁日日躁狠狠躁av麻豆男男| 国产一区二区不卡老阿姨| 三级一区二区三区| 国产主播一区二区三区| 亚洲视频一二三四| 久久99国产精品免费网站| 日本特黄a级片| 日本女优在线视频一区二区| 91香蕉视频污版| 首页国产欧美久久| 91看片就是不一样| 久久久精品日韩| 99久久久无码国产精品6| 奶水喷射视频一区| 久草在在线视频| 日本欧美在线看| 亚洲另类第一页| 国产一区在线观看视频| 国产精品无码自拍| 99久久伊人精品| theav精尽人亡av| 国产婷婷精品av在线| 亚洲一级片在线播放| 中文字幕一区二区三区在线观看| 精品国产国产综合精品| 亚洲激情网站免费观看| 日本一区二区三区四区五区| 精品国产精品自拍| 亚洲国产精品无码久久久| 欧美午夜影院一区| 国产伦一区二区| 精品福利在线导航| 五月婷婷丁香网| 亚洲无线码在线一区观看| 天堂аⅴ在线地址8| 欧美精品一区二区免费| 538视频在线| 国产91在线高潮白浆在线观看| 国产成人久久精品麻豆二区| 国产精品偷伦一区二区| 精品中文字幕一区二区三区| 国产在线精品一区二区中文 | 国产视频精品一区二区三区| 第一页在线观看| 欧美成人四级hd版| 中文字幕21页在线看| 国产精品一区二区久久久 | 国产日韩欧美二区| 精品九九在线| 国产传媒久久久| 丝袜亚洲另类欧美综合| 在线视频一二区| 97久久精品人人做人人爽50路| 国产精品情侣呻吟对白视频| 亚洲精品国产精华液| 成年人视频在线免费看| 欧美日韩国产首页| 女人18毛片一区二区三区| 一区二区三区黄色| 黄网在线免费看| 国产精品爽爽爽| 欧美激情极品| 中文字幕日韩精品一区二区| 亚洲一区二区网站| 奇米777在线| 国产欧美精品一区二区三区四区 | 欧美日韩视频在线| 国产又粗又黄视频| 亚洲欧美日韩一区二区在线| 中文字幕在线观看网站| 国产成人啪精品视频免费网| 亚洲成人黄色| 亚洲精品国产精品国自产观看| 在线成人欧美| 99999精品| 中文字幕欧美日韩一区| 午夜精品三级久久久有码| 欧美一区二区在线看| 国产高清视频免费最新在线| 久久久久久久久久久网站| 91麻豆精品国产91久久久更新资源速度超快| 精品国产一区二区三区久久久久久| 欧美国产三区| 污网站免费在线| 久久人人超碰精品| 91在线看视频| 日韩免费电影网站| 老司机在线永久免费观看| 国产福利精品在线| 国产成人精品免费视| 欧美日韩精品在线一区二区| 国产成人精品免费一区二区| 小向美奈子av| 欧美日韩精品综合在线| 国产裸舞福利在线视频合集| 欧亚精品在线观看| 亚洲大片精品免费| 国产成人精品视频免费看| 成人精品视频一区二区三区尤物| 黑人巨大精品一区二区在线| 在线播放国产精品二区一二区四区| 搞黄视频免费在线观看| 国产成人亚洲综合91| 亚洲免费成人av在线| 成人毛片一区二区| 99久久免费精品| 成人毛片18女人毛片| 精品亚洲一区二区三区四区五区| 九九色在线视频| 国产精品视频免费观看| 在线成人www免费观看视频| 一边摸一边做爽的视频17国产| 亚洲国产另类av| 天堂成人在线视频| 69久久夜色精品国产69| 亚洲人成亚洲精品| 欧美一级黄色影院| 国产精品国产三级国产普通话99 | 欧美专区一二三| 日韩精品91亚洲二区在线观看 | 亚洲欧美国产77777| 99国产在线播放| 欧美精品videosex性欧美| 免费观看成人www动漫视频| 欧美黄色免费影院| 国产免费久久精品| 一级片免费网站| 欧美精品亚州精品| 欧美亚洲tv| 欧美成人黄色网址| 亚洲欧洲日韩一区二区三区| 国产亲伦免费视频播放| 欧美激情高清视频| 丝袜久久网站| 中文字幕网av| 一区二区国产盗摄色噜噜| 亚洲av成人精品毛片| 国产精品热视频| 欧美日韩精品一本二本三本 | 国产精品自在| 日韩精品一区二区三区不卡| 国产精品色呦呦| 亚洲av综合色区无码一二三区| 欧美亚洲成人精品| 国产高清一区二区| 欧美深性狂猛ⅹxxx深喉| 欧美伊人久久久久久久久影院 | 日本成人黄色网| 亚洲视频精选在线| 欧美特黄一级视频| 国产精品美腿一区在线看| 激情综合自拍| jizzjizzjizz国产| 亚洲第一精品久久忘忧草社区|