设备树知识点
注意事项
编写设备树文件,一定要保证引脚没有被占用。
设备树
dts (device tree source) 描述SOC外部外设信息的设备树文件。
dtsi (device tree source include) 描述SOC内部外设信息的设备树文件,可以被包含到其他.dts文件中。
dtb (device tree blob) 经编译工具生成的设备树二进制文件
dtc (device tree compiler) 设备树编译工具
在Linux系统终端下使用make dtbs命令,来编译设备树文件,生成dtb文件。
设备树节点命名格式:
节点命名格式:
节点标签:节点名称@设备地址,可以通过&节点标签来直接访问这个节点。
设备树结构:设备树+设备树节点追加内容
设备树是一个包含节点和属性的简单树状结构。属性就是键值对,而节点可以同时包含属性和子节点。
/ {
model = "Freescale i.MX6 ULL 14x14 EVK Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
chosen {
stdout-path = &uart1;
};
memory {
reg = <0x80000000 0x20000000>;
};
led {
compatible = "gpio-leds";
led0{
label = "red_led";
gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
status = "okay";
};
};
beep {
compatible = "myboard-beep";
label = "red";
beep-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
status = "okay";
};
key {
#address-cells = <1>;
#size-cells = <1>;
label = "yellow_key";
compatible = "myboard-key";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_key>;
gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
interrupt-parent = <&gpio1>;
interrupts = <18 IRQ_TYPE_EDGE_BOTH>;
status = "okay";
};
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
pinctrl_led: ledgrp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x30b0
>;
};
pinctrl_key: keygrp {
fsl,pins = <
MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0xf080
>;
};
pinctrl_ecspi3: icm20608 {
fsl,pins = <
MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x10b0
MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x10b1
MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO 0x10b1
MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI 0x10b1
>;
};
};
};
&ecspi3 {
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi3>;
status = "okay";
spidev: icm20608@0 {
compatible = "myboard,icm20608";
spi-max-frequency = <8000000>;
reg = <0>;
};
};
&wdog1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wdog>;
fsl,wdog_b;
};
该设备树包括:
一个单独的根节点 /
两个子节点 node1 node2
两个子节点的子节点 child-node1 child-node2
一堆分散在树里的属性
设备树的基本单元是node,这些node被组织成树形。
设备树内容都是以key-value键值对的形式存在的。
设备树节点和属性
节点命名格式:节点标签:节点名称@设备地址
model:
chosen:
memory:
aliases节点:
格式:property = &label;
这与之前的phandle = <&label>;形式不同,这是把一个phandle值插入到一个cell。
compatible = "ovti,ov9650";
compatible:该字符串的格式是<制造商>,<型号>。
compatible:兼容性属性,用来决定操作系统使用哪个设备驱动来绑定设备。
status = "okay"; status = "disabled";
status:状态属性
GPIO:
gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
gpios = <&gpio4 22 1>;
cs-gpios = <&gpio5 7 0>;
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
};
pinctrl-names = "default", "state_100mhz", "state_200mhz";定义了设备有三种状态。
pinctrl-0,pinctrl-1,pinctrl-2:定义了该设备状态的对应引脚。
范围(地址转换):
ranges:
中断:
interrupt-parent = <&gpio1>;
interrupt-parent:这是一个设备节点的属性。包含一个指向该设备连接的中断控制器的phandle。那些没有interrupt-parent的节点则从它们的父节点中继承该属性。
interrupt-controller;
interrupt-controller:中断控制器。一个空的属性定义表示该节点作为一个接收中断信号的设备。
#interrupt-cells = <2>;
#interrupt-cells:这是一个中断控制器节点的属性。它声明了该中断控制器的中断指示符中cell的个数(类似于#address-cells和#size-cells)。
interrupts = <18 IRQ_TYPE_EDGE_BOTH>;
interrupts:中断输入线。包含一个中断指示符的列表,对应于该设备上的每个中断输出信号。
interrupt-names = "complete";
interrupt-names:为interrupts属性中的每个中断指定一个名称。
其他属性:
clock-names:clocks属性中命名clocks。
dma-names:用于dma属性。
父节点属性:
#address-cells:属性值决定了子节点reg属性中地址信息所占用的字长(32 位)。(地址)
#size-cells:属性值决定了子节点reg属性中长度信息所占的字长(32 位)。(长度)
子节点属性:
reg = <0x80000000 0x20000000>;
reg:该属性的格式是<[地址1 长度1][地址2 长度2][地址3 长度3]...>
reg:如果一个节点有reg属性,那么该节点的名字就必须包含设备地址,这个设备地址就是reg属性里第一个地址值。
reg:reg属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息。
reg-names:reg属性中的内存区域列表。
cpu节点:
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
内存映射设备:
#address-cells = <1>;
#size-cells = <1>;
reg = <0x10100000 0x1000>;
带独立片选线的设备:
#address-cells = <2>;
#size-cells = <1>;
reg = <1 0 0x1000>;
reg = <片选号 偏移量 长度>;
非内存映射设备:
#address-cells = <1>;
#size-cells = <0>;
spi@58{
reg = <58>;
};