轉自:https://blog.csdn.net/qq_39507748/article/details/105877952 學習使用。
一、節點的命名格式
1 / { 2 aliases { 3 can0 = &flexcan1; 4 }; 5 6 cpus { 7 #address-cells = <1>; 8 #size-cells = <0>; 9 10 cpu0: cpu@0 { 11 compatible = "arm,cortex-a7"; 12 device_type = "cpu"; 13 reg = <0>; 14 }; 15 }; 16 17 intc: interrupt-controller@00a01000 { 18 compatible = "arm,cortex-a7-gic"; 19 #interrupt-cells = <3>; 20 interrupt-controller; 21 reg = <0x00a01000 0x1000>, 22 <0x00a02000 0x100>; 23 }; 24 }
第 1 行,“/”
是根節點,每個設備樹文件只有一個根節點。其實在dts
和 dtsi
文件中都有根節點,但是並不會出錯,因為這兩個“/”根節點的內容會合並到一個根節點中。
第2、6 和 17 行,aliases
、cpus
和 intc
是三個子節點,在設備樹中節點命名格式如下:
其中“node-name”是節點名字,為 ASCII 字符串,節點名字應該能夠清晰的描述出節點的功能,比如“uart1”就表示這個節點是 UART1外設。“unit-address”一般表示設備的地址或寄存器首地址,如果某個節點沒有地址或者寄存器的話“unit-address”可以不要,比如“cpu@0”、“interrupt-controller@00a01000”。
但是我們在上述代碼中我們看到的節點命名卻如下所示:
上述命令並不是“node-name@unit-address”
這樣的格式,而是用“:”
隔開成了兩部分,“:”
前面的是節點標簽(label)
,“:”
后面的才是節點名字,格式如下所示:
引入label 的目的就是為了方便訪問節點,可以直接通過&label 來訪問這個節點,比如通過&cpu0 就可以訪問“cpu@0”這個節點,而不需要輸入完整的節點名字。再比如節點 “intc: interrupt-controller@00a01000”,節點 label是intc,而節點名字就很長了,為“interrupt-controller@00a01000”。很明顯通過&intc來訪問“interrupt-controller@00a01000”這個節點要方便很多。
第10 行,cpu0
也是一個節點,只是 cpu0
是 cpus
的子節點。每個節點都有不同屬性,不同的屬性又有不同的內容,屬性都是鍵值對,值可以為空或任意的字節流。設備樹源碼中常用的幾種數據形式如下所示:
1.1、字符串
上述代碼設置 compatible
屬性的值為字符串“arm,cortex-a7”。
2.2、32 位無符號整數
上述代碼設置 reg
屬性的值為 0,reg
的值也可以設置為一組值,比如:
3.3、字符串列表
屬性值也可以為字符串列表,字符串和字符串之間采用“,”
隔開,如下所示:
上述代碼設置屬性 compatible
的值為“fsl,imx6ull-gpmi-nand”和“fsl, imx6ul-gpmi-nand”。
二、常見屬性
節點是由一堆的屬性組成,節點都是具體的設備,不同的設備需要的屬性不同,用戶可以自定義屬性。除了用戶自定義屬性,有很多屬性是標准屬性,Linux 下的很多外設驅動都會使用這些標准屬性。
1、compatible 屬性
compatible屬性也叫做“兼容性”屬性,這是非常重要的一個屬性!compatible 屬性的值是一個字符串列表,compatible屬性用於將設備和驅動綁定起來。字符串列表用於選擇設備所要使用的驅動程序,compatible 屬性的值格式如下所示:
其中 manufacturer 表示廠商,model一般是模塊對應的驅動名字。比如imx6ull-alientek-emmc.dts中 sound節點是 I.MX6U-ALPHA 開發板的音頻設備節點,I.MX6U-ALPHA開發板上的音頻芯片采用的歐勝(WOLFSON)出品的 WM8960,sound節點的 compatible 屬性值如下:
屬性值有兩個,分別為“fsl,imx6ul-evk-wm8960”和“fsl,imx-audio-wm8960”,其中“fsl”表示廠商是飛思卡爾,“imx6ul-evk-wm8960”和“imx-audio-wm8960”表示驅動模塊名字。sound這個設備首先使用第一個兼容值在 Linux 內核里面查找,看看能不能找到與之匹配的驅動文件,如果沒有找到的話就使用第二個兼容值查找,直到找到或者查找完整個 Linux 內核也沒有找到對應的驅動。
一般驅動程序文件都會有一個OF
匹配表,此 OF
匹配表保存着一些 compatible
值,如果設備節點的 compatible
屬性值和OF
匹配表中的任何一個值相等,那么就表示設備可以使用這個驅動。比如在文件imx-wm8960.c
中有如下內容。
第 632~635 行的數組 imx_wm8960_dt_ids 就是 imx-wm8960.c這個驅動文件的匹配表,此匹配表只有一個匹配值“fsl,imx-audio-wm8960”。如果在設備樹中有哪個節點的compatible 屬性值與此相等,那么這個節點就會使用此驅動文件。
第 642 行,wm8960采用了platform_driver驅動模式,關於 platform_driver驅動后面會講解。此行設置.of_match_table為 imx_wm8960_dt_ids,也就是設置這個platform_driver所使用的OF 匹配表。
2、model 屬性
model 屬性值也是一個字符串,一般 model 屬性描述設備模塊信息,比如名字什么的,比如:
3、status 屬性
status屬性看名字就知道是和設備狀態有關的,status屬性值也是字符串,字符串是設備的狀態信息,可選的狀態如下表所示:
4、#address-cells 和#size-cells 屬性
這兩個屬性的值都是無符號 32 位整形,#address-cells 和#size-cells這兩個屬性可以用在任何擁有子節點的設備中,用於描述子節點的地址信息。#address-cells屬性值決定了子節點reg 屬性中地址信息所占用的字長(32 位),#size-cells屬性值決定了子節點 reg屬性中長度信息所占的字長(32 位)。#address-cells 和#size-cells 表明了子節點應該如何編寫reg屬性值,一般 reg 屬性都是和地址有關的內容,和地址相關的信息有兩種:起始地址和地址長度,reg屬性的格式一為:
每個“address length”組合表示一個地址范圍,其中 address是起始地址,length是地址長度,#address-cells表明 address這個數據所占用的字長,#size-cells表明length這個數據所占用的字長,比如:
第 3,4 行,節點 spi4的#address-cells = <1>,#size-cells = <0>,說明spi4的子節點reg 屬性中起始地址所占用的字長為 1,地址長度所占用的字長為 0。
第 8 行,子節點gpio_spi: gpio_spi@0 的 reg屬性值為 <0>,因為父節點設置了#address-cells = <1>,#size-cells = <0>,因此 addres=0,沒有length的值,相當於設置了起始地址,而沒有設置地址長度。
第 14,15 行,設置aips3: aips-bus@02200000節點#address-cells = <1>,#size-cells = <1>,說明aips3: aips-bus@02200000節點起始地址長度所占用的字長為 1,地址長度所占用的字長也為 1。
第 19 行,子節點 dcp: dcp@02280000 的reg屬性值為<0x02280000 0x4000>,因為父節點設置了#address-cells = <1>,#size-cells = <1>,address= 0x02280000,length= 0x4000,相當於設置了起始地址為0x02280000,地址長度為0x40000。
5、reg 屬性
reg
屬性前面已經提到過了,reg
屬性的值一般是(address,length)對。reg
屬性一般用於描述設備地址空間資源信息,一般都是某個外設的寄存器地址范圍信息,比如在imx6ull.dtsi
中有如下內容:
上述代碼是節點uart1,uart1節點描述了I.MX6ULL的 UART1相關信息,重點是第 326 行 的reg 屬性。其中uart1的父節點 aips1: aips-bus@02000000設置了#address-cells = <1>、#size-cells = <1>,因此reg屬性中address=0x02020000,length=0x4000。查閱《I.MX6ULL 參考手冊》可知,I.MX6ULL的 UART1寄存器首地址為0x02020000,但是 UART1的地址長度(范圍)並沒有 0x4000這么多,這里我們重點是獲取 UART1寄存器首地址。
6、ranges 屬性
ranges屬性值可以為空或者按照(child-bus-address,parent-bus-address,length)格式編寫的數字矩陣,ranges 是一個地址映射/轉換表,ranges屬性每個項目由子地址、父地址和地址空間長度這三部分組成:
child-bus-address:子總線地址空間的物理地址,由父節點的#address-cells 確定此物理地址所占用的字長。
parent-bus-address:父總線地址空間的物理地址,同樣由父節點的#address-cells確定此物理地址所占用的字長。
length:子地址空間的長度,由父節點的#size-cells確定此地址長度所占用的字長。如果ranges屬性值為空值,說明子地址空間和父地址空間完全相同,不需要進行地址轉換,對於我們所使用的.MX6ULL 來說,子地址空間和父地址空間完全相同,因此會在imx6ull.dtsi中找到大量的值為空的ranges 屬性,如下所示:
三、 根節點 compatible 屬性
每個節點都有 compatible
屬性,根節點“/”
也不例外,imx6ull-alientek-emmc.dts
文件中根節點的 compatible
屬性內容如下所示:
可以看出,compatible有兩個值:“fsl,imx6ull-14x14-evk”和“fsl,imx6ull”。前面我們說了,設備節點的 compatible屬性值是為了匹配 Linux 內核中的驅動程序,那么根節點中的 compatible屬性是為了做什么工作的? 通過根節點的compatible屬性可以知道我們所使用的設備,一般第一個值描述了所使用的硬件設備名字,比如這里使用的是“imx6ull-14x14-evk”這個設備,第二個值描述了設備所使用的 SOC,比如這里使用的是“imx6ull”這顆 SOC。Linux 內核會通過根節點的compoatible 屬性查看是否支持此設備,如果支持的話設備就會啟動 Linux 內核。
————————————————
原文鏈接:https://blog.csdn.net/qq_39507748/article/details/105877952