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