前言

曾经有大神跟我说Linux驱动的本质是读写寄存器,我不以为然,直到后来我认真理解了Linux的设备树机制 ……

节点

根节点的定义,以/开头,它可以跨多个文件定义

1
2
3
/ {
......
}

SOC信息描述,以RK3399 SOC为例

1
2
model = "Rockchip RK3399 Excavator Board (Linux Opensource)";
compatible = "rockchip,rk3399-excavator-v10-linux", "rockchip,rk3399";

普通的节点定义,不带标签意味着它不需要在别处引用

1
2
3
gpio-keys {
......
};

带标签是为了在别处能够访问,格式:标签名: 节点名,后面跟一个括号{ … };

1
2
3
4
/* 标签名: 节点名 */
gpio_keys: gpio-keys {
......
};

通常使用&标签名来引用一个节点,引用一个节点意味着追加、补充这个节点的配置信息

1
2
3
4
/* 追加、补充这个节点的配置信息 */
&gpio_keys {
......
};

匹配信息,用compatible表示,这个相当于节点的身份信息

1
compatible = "gpio-keys";

寄存器

寄存器定义格式:<高32位地址 低32位地址 高32位长度 低32位长度>,由于RK3399是64位处理器的缘故,address-cells为1代表4个字节

1
2
3
4
5
6
7
i2c0: i2c@ff3c0000 {
compatible = "rockchip,rk3399-i2c";
reg = <0x0 0xff3c0000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};

时钟源

一般可选多个时钟源,看外设的需要,i2c需要2个时钟源:一个给SCL,一个提供寄存器访问,时钟源信息一般在./include/dt-bindings/clock/rk3399-cru.h里边给出,clocksclock-names是按顺序匹配的

1
2
clocks =  <&pmucru SCLK_I2C0_PMU>, <&pmucru PCLK_I2C0_PMU>;
clock-names = "i2c", "pclk";

中断

中断配置存在头文件当中:include/dt-bindings/interrupt-controller/arm-gic.h和include/dt-bindings/interrupt-controller/irq.h

1
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH 0>;

GPIO

RK3399 GPIO0表示第0个bank的GPIO,第0个bank的GPIO索引:0-31,分为A、B、C、D四组,以下对应的是GPIO0_B4管脚:B代表1,1x8+4=12

1
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;

以下对应的是GPIO4_C6管脚:C代表2,2x8+6=22

1
gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;

引脚

引脚复用(也就是说一个引脚它可能是GPIO,也可以是USART_RXD,或者是I2C_SCL)

1
2
pinctrl-names = "default";
pinctrl-0 = <&i2c0_xfer>;

补充定义pinctrl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
&pinctrl {
sdmmc-pwrseq {
sdcard_enable_h: sdcard-enable-h {
rockchip,pins =
<1 20 RK_FUNC_GPIO &pcfg_pull_none>;
};
};

/* add by cym 20190508 */
lsm330_a {
lsm330a_irq_gpio: lsm330a-irq-gpio {
rockchip,pins = <1 22 RK_FUNC_GPIO &pcfg_pull_none>;
};
};

lsm330_g {
lsm330g_irq_gpio: lsm330g-irq-gpio {
rockchip,pins = <1 24 RK_FUNC_GPIO &pcfg_pull_none>;
};
};

ak8963 {
ak8963_irq_gpio: ak8963-irq-gpio {
rockchip,pins = <1 0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};

cm3218 {
cm3218_irq_gpio: cm3218-irq-gpio {
rockchip,pins = <4 24 RK_FUNC_GPIO &pcfg_pull_up>;
};
};

leds {
led1_ctl: led1-ctl {
rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_up>;
};
};

buzzer {
beep_gpio: beep-gpio {
rockchip,pins = <4 22 RK_FUNC_GPIO &pcfg_pull_up>;
};
};

gt911 {
gt911_gpio: gt911-gpio {
rockchip,pins = <1 9 RK_FUNC_GPIO &pcfg_pull_up>,<1 20 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
/* end add */

lcd-panel {
lcd_panel_reset: lcd-panel-reset {
/*rockchip,pins = <2 27 RK_FUNC_GPIO &pcfg_pull_down>;*/
rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
};

lcd_panel_pwr_en: lcd-panel-pwr-en {
rockchip,pins = <3 16 RK_FUNC_GPIO &pcfg_pull_down>;
lcd_panel_lcd_en:lcd-panel-lcd-en {
rockchip,pins = <1 4 RK_FUNC_GPIO &pcfg_pull_down>;
};
};

};

};

IO复用需要通过标签名方式来引用,以下代码的sdmmc-pwrseq、lsm330_a、lsm330_g … 是分类的作用

功能模块 节点标签 引脚位置 复用功能 电气属性
SD卡电源控制 sdcard_enable_h GPIO1_B4 (Bank1, Pin20) RK_FUNC_GPIO 无上下拉 (none)
加速度计 lsm330a_irq_gpio GPIO1_B6 (Bank1, Pin22) RK_FUNC_GPIO 无上下拉 (none)
陀螺仪 lsm330g_irq_gpio GPIO1_B8 (Bank1, Pin24) RK_FUNC_GPIO 无上下拉 (none)
磁力计 ak8963_irq_gpio GPIO1_A0 (Bank1, Pin0) RK_FUNC_GPIO 无上下拉 (none)
光传感器 cm3218_irq_gpio GPIO4_D0 (Bank4, Pin24) RK_FUNC_GPIO 上拉 (pull_up)
LED控制 led1_ctl GPIO0_B4 (Bank0, Pin12) RK_FUNC_GPIO 上拉 (pull_up)
蜂鸣器 beep_gpio GPIO4_C6 (Bank4, Pin22) RK_FUNC_GPIO 上拉 (pull_up)
触摸屏 gt911_gpio GPIO1_A9 (Bank1, Pin9) RK_FUNC_GPIO 上拉 (pull_up)
GPIO1_B4 (Bank1, Pin20) RK_FUNC_GPIO 上拉 (pull_up)
LCD面板 lcd_panel_reset GPIO4_D6 (Bank4, Pin30) RK_FUNC_GPIO 无上下拉 (none)
lcd_panel_pwr_en GPIO3_D0 (Bank3, Pin16) RK_FUNC_GPIO 下拉 (pull_down)
lcd_panel_lcd_en GPIO1_A4 (Bank1, Pin4) RK_FUNC_GPIO 下拉 (pull_down)

节点状态

用status字段表示:一般有okay和disabled两种状态

1
status = "disabled";

答疑

  1. 引用节点的话可以改变原有的内容吗?还是只能新增:补充和新增
  2. RK3399的GPIO映射关系:参考上面GPIO小结:一个BANK(0-31)分为A、B、C、D四组
  3. 根节点可以放在多个文件之中吗?:可以的

术语

  • dtc:device tree compiler,设备树编译工具
  • dts:device tree source,设备树源文件
  • dtsi:device tree source include,设备树头文件
  • dtb:device tree blob,设备树文件(二进制)

© 2025 hywing 使用 Stellar 创建
总访问 113701 次 | 本页访问 326