前面整了很多虚头巴老的东西,这个部分来看看实例,一个dts到底有什么东西。
这里先讲最近我遇到的三个属性,内容是来自某位前辈的blog,但是我搞忘链接了,抱歉。
设备树是由节点组成的,节点是由一堆属性组成的,节点都是具体的设备, 不同的设备需要的属性不同,用户可以自定义属性。
除了用户自定义属性,有很多属性都是标准属性。
1. compatible属性
ksms驱动中of_find_compatible_node,就是查找节点的compatible属性。
compatible属性也叫做“兼容性”属性,是一个字符串列表,compatible属性用于将设备和驱动绑定起来。
字符串列表用于选择设备所要使用的驱动程序,格式如下所示
“manufacturer,model”
其中manufacturrer表示厂商,model一般是模块对应的驱动名字。比如像下面这个sound节点
sound { compatible = "fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960"; . . . . . . }
属性分别是“fsl,imx6ul-evk-wm8960”和“fsl,imx-audio-wm8960”,其中“fsl” 表示厂商是飞思卡尔,“imx6ul-evk-wm8960”和“imx-audio-wm8960”表示驱动模块名字,这个设备首先使用第一个兼容值在 Linux 内核里面查找,看看能不能找到与之匹配的驱动文件,如果没有找到的话就使用第二个兼容值查。
设备树可描述的信息
·CPU的数量和类别。 ·内存基地址和大小。 ·总线和桥。 ·外设连接。 ·中断控制器和中断使用情况。 ·GPIO控制器和GPIO使用情况。 ·时钟控制器和时钟使用情况。
2、 #address-cells和#size-cells属性
我们看见dts文件最上面有个 #address-cells和#size-cells。这两个属性的值都是无符号32位整型,用于描述子节点的地址信息。
#address-cells属性值决定了子节点reg属性中地址信息所占用的字长(32位)
#size-cells属性值决定了子节点reg属性中**长度信息所占的字长(**32 位)
整个栗子瞅瞅:
spi4 { compatible = "spi-gpio"; #address-cells = <1>; #size-cells = <0>; gpio_spi: gpio_spi@0 { compatible = "fairchild,74hc595"; reg = <0>; }; }
节点 spi4 的#address-cells = <1>, #size-cells = <0>,说明 spi4 的子节点 reg 属性中起始地址所占用的字长为 1,地址长度所占用的字长为 0。
因为父节点设置了#address cells = <1>, #size-cells = <0>,因此 addres=0,没有 length 的值,相当于设置了起始地址而没有设置地址长度。
#address-cells = <2>; #size-cells = <2>;
相当于reserved-memory设备的属性的起始地址信息占用的字长为两位,这个地址长度为两位。这两个信息都是针对属性的。
有点绕,我觉得就是一个是知道了起始地址的位置,然后告诉你从这个起始位置走多远。
起始地址用多长来描述–》#address-cells = <2>;
走多远用多长来描述–》#size-cells = <2>;
3、reg属性
上一部分的#address-cells 和#size-cells 表明了子节点应该如何编写 reg 属性值,一般 reg 属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度, reg 属性的格式一为:
reg = <address1 length1 address2 length2 address3 length3……>
reg 属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息,比如在 imx6ull.dtsi 中有如下内容:
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"; };
(这个肯定对应的 #address-cells = <1>; #size-cells = <1>;)
reg = <0x02020000 0x4000>;
上述代码是节点 uart1, uart1 节点描述了 I.MX6ULL 的 UART1 相关信息,重点是第 326 行的 reg 属性。
其中 uart1 的父节点 aips1: aips-bus@02000000 设置了#address-cells = <1>、 #sizecells = <1>,因此 reg 属性中 address=0x02020000, length=0x4000。
查阅《I.MX6ULL 参考手册》可知, I.MX6ULL 的 UART1 寄存器首地址为 0x02020000,但是 UART1 的地址长度(范围)并没有 0x4000 这么多,这里我们重点是获取 UART1 寄存器首地址。