正点原子----Linux设备树详解
linux設備樹
- 1、什么是設備樹
- 2、DTS、DTB、DTC的關系
- 3、如何編譯設備樹
- 4、DTS基本結構
- 4.1、語法
- 4.2、設備樹在系統中的體現
- 4.3、嘗試自己添加節點
- 4.4、嘗試對根節點追加信息
- 5、設備樹特殊節點
- 5.1、chosen子節點
- 5.2、aliases子節點
- 6、設備樹中標準屬性
- 6.1、compatilbe屬性
- 6.2、model屬性
- 6.3、status屬性
- 6.4、reg屬性
- 6.5、#address-cells和#size-cells
- 7、OF操作函數
- 7.1、OF函數查找節點
- ① of_find_node_by_name
- ② of_find_compatible_node
- ③ of_find_node_by_path
- 7.2、查找父子節點的OF函數
- ① of_get_parent
- ② of_get_next_child
- 7.3、提取屬性值的OF函數
- ① of_find_property
- ② of_property_read_u32_index
- ③ of_property_read_u8_array
- ④ of_property_read_u8
1、什么是設備樹
????????
????????設備樹DTS(Device Tree Source),DTS文件用樹形結構描述板級設備,也就是開發板上的設備信息,比如CPU數量,內存基地址,IIC接口上接了哪些設備等等,如下圖:
2、DTS、DTB、DTC的關系
????????1、DTS是設備樹的源文件
????????2、DTB是DTS編譯后得到的二進制文件
????????3、DTC是DTS的編譯工具,源碼在內核的scripts/dtc目錄下面,如下:
3、如何編譯設備樹
????????1、make dtbs:編譯所有的dts文件;
????????2、make xxx.dts:編譯指定的dts文件按;
4、DTS基本結構
????????設備樹也有頭文件,擴展名為.dtsi
4.1、語法
????????1、根節點:/
????????2、從/根節點開始描述設備信息
????????3、在/根節點外有一些&cpu0這樣的語句是“追加”
????????這里以imx6ull-alientek-emmc.dts為例,下圖chosen,memor為子節點
????????4、節點名字完整的要求:node-name@unit-address,例如:
i2c4: i2c@021f8000 {#address-cells = <1>;#size-cells = <0>;compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";reg = <0x021f8000 0x4000>;interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_I2C4>;status = "disabled";};????????后面0x021f8000為i2c4的起始地址。
????????5、還可以為節點加標簽,在設備樹也是很常見的,例如:
????????lable:node-name@unit-address
????????lable為標簽,后面node-name是名字。加lable的目的是為了后面訪問追加時方便。
4.2、設備樹在系統中的體現
????????1、系統啟動以后可以在根文件系統里面可以看到設備樹節點信息,在/proc/device-tree/目錄下存放著設備樹信息,一級子節點。一級子節點內還有二級子節點。
4.3、嘗試自己添加節點
????????1、在imx6ull-alientek-emmc.dts根節點下添加如下內容
????????2、make dtbs編譯,拷貝到tftp目錄下,重啟開發板,進入到/proc/device-tree目錄下即可看到添加的節點
4.4、嘗試對根節點追加信息
????????1、添加之前intc節點目錄內容如下:
????????2、在imx6ull-alientek-emmc.dts下加入如下內容
????????3、編譯、拷貝、重啟開發板,追加節點信息如下:
5、設備樹特殊節點
5.1、chosen子節點
????????1、chosen并不是一個真實的節點,主要目的是將uboot里面的bootargs環境變量傳遞給linux內核,作為命令行參數。
????????uboot里面的bootargs為:
????????kernel中bootargs為:
????????2、經過查看chosen節點中包含bootargs屬性,但是我們在設備樹里面并沒有設置bootargs。
????????3、這是因為在uboot過程中fdt_chosen函數會將bootargs傳給內核,在uboot源碼中common/fdt_support.c文件內,如下:
5.2、aliases子節點
????????aliaese的意思是 “別名” ,給節點起另一個名字。
6、設備樹中標準屬性
6.1、compatilbe屬性
????????1、copatible屬性叫做兼容性,值是一個字符串列表,compatible屬性用來將設備和驅動綁定起來,其格式一般為“manufacturer,model”。
????????2、在驅動中of_device_id機構提匹配表,保存著一些compatible值,如果設備節點的compatible屬性值和of匹配表中的任何一個值相等,就會調用probe函數。
6.2、model屬性
????????model屬性值也是一個字符串,描述設備模塊信息,比如名字:
model = "wm8960-audio";6.3、status屬性
狀態
????????okay:表示設備可操作
????????disable:表示設備不可操作
6.4、reg屬性
????????reg屬性值一般是(address,length),描述設備地址空間資源,一般都是某個外設的寄存器地址范圍信息,如:
uart1: serial@02020000 {compatible = "fsl,imx6ul-uart","fsl,imx6q-uart", "fsl,imx21-uart";reg = <0x02020000 0x4000>;interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_UART1_IPG>,<&clks IMX6UL_CLK_UART1_SERIAL>;clock-names = "ipg", "per";status = "disabled"; };6.5、#address-cells和#size-cells
????????1、這兩個屬性值都是無符號32位整形。address-cells屬性絕對了子節點reg屬性中地址信息所占用的字長,size-cells屬性值決定了子節點reg屬性中長度信息所占用的字長。如:
spi4 {compatible = "spi-gpio";#address-cells = <1>;#size-cells = <0>;gpio_spi: gpio_spi@0 {compatible = "fairchild,74hc595";reg = <0>;}; };aips3: aips-bus@02200000 {compatible = "fsl,aips-bus", "simple-bus";#address-cells = <1>;#size-cells = <1>;dcp: dcp@02280000 {compatible = "fsl,imx6sl-dcp";reg = <0x02280000 0x4000>;}; };????????2、spi4的address=1,size=1,說明spi4的子節點reg屬性中起始地址所占用字長為1,地址長度所占用字長位0
????????3、gpio_spi: gpio_spi@0節點中的reg屬性:reg = <0>,是因為父節點設置了address=1,size=0。
????????aips3也同樣理解。
7、OF操作函數
????????1、在驅動中使用OF函數獲取設備屬性內容。設備都是以節點的形式掛到設備樹上,因此要想獲取這個設備的其他屬性信息,必須先獲取節點。
????????2、Linux內核使用device_node結構體來描述一個節點,此結構體定義在include/linux/of.h中。
7.1、OF函數查找節點
① of_find_node_by_name
struct device_node *of_find_node_by_name(struct device_node *from,const char *name);參數:
????????1、form:開始查找的節點,如果為NULL表示從根節點開始查找整個設備樹name:要查找的節點名字
????????2、返回值:找到的節點,如果為NULL表示查找失敗
② of_find_compatible_node
參數:
????????1、from:開始查找的節點,如果為 NULL 表示從根節點開始查找整個設備樹。
????????2、type:要查找的節點對應的 type 字符串,也就是 device_type 屬性值,可以為 NULL,表示忽略掉 device_type 屬性。
????????3、compatible: 要查找的節點所對應的 compatible 屬性列表。
????????4、返回值: 找到的節點,如果為 NULL 表示查找失敗
③ of_find_node_by_path
參數:
????????1、path:帶有全路徑的節點名,可以使用節點的別名,比如“/backlight”就是 backlight 這個節點的全路徑。
????????2、返回值: 找到的節點,如果為 NULL 表示查找失敗
7.2、查找父子節點的OF函數
????????參數就不介紹了,使用較少。
① of_get_parent
② of_get_next_child
7.3、提取屬性值的OF函數
????????節點的屬性信息里面保存了驅動所需要的內容,Linux內核中使用結構體property表示屬性,此結構體定義在of.h文件中,如下:
struct property {char *name; /* 屬性名字 */int length; /* 屬性長度 */void *value; /* 屬性值 */struct property *next; /* 下一個屬性 */unsigned long _flags;unsigned int unique_id;struct bin_attribute attr; };① of_find_property
????????該函數用于查找指定的屬性,函數原型:
property *of_find_property(const struct device_node *np,const char *name,int *lenp)參數介紹:
????????1、np:設備節點
????????2、name:屬性名字
????????3、lenp:屬性值的字節數
????????4、返回值:找到的屬性
② of_property_read_u32_index
????????從屬性中獲取指定標號的u32類型數據值,函數原型如下:
int of_property_read_u32_index(const struct device_node *np,const char *propname,u32 index,u32 *out_value)③ of_property_read_u8_array
????????讀取屬性中u8類型的數組數據,也可以讀u16、u32、u64類型的,函數原型如下:
int of_property_read_u8_array(const struct device_node *np,const char *propname,u8 *out_values,size_t sz)④ of_property_read_u8
????????讀取之后一個整形值的屬性,函數原型如下:
int of_property_read_u8(const struct device_node *np,const char *propname,u8 *out_value)下篇使用OF函數獲取設備樹節點信息。
總結
以上是生活随笔為你收集整理的正点原子----Linux设备树详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于S2SH+ExtJS4+Oracle
- 下一篇: linux视频采集软件,嵌入式LINUX