3. RK平台设备树基础:设备树语法回顾、compatible属性、reg属性、中断属性、pinctrl属性

设备树(Device Tree)是RK平台驱动开发的核心数据描述语言。它负责将硬件拓扑、寄存器地址、中断资源、引脚复用等静态信息传递给内核,让驱动代码与硬件描述解耦。本章聚焦Sensor驱动移植中最常打交道的5个设备树要素:语法基础、compatible匹配、reg地址、中断绑定、pinctrl引脚控制。

学习提示: 在RK平台上,设备树文件通常位于 arch/arm64/boot/dts/rockchip/ 目录下,以 .dts 或 .dtsi 为后缀。Sensor驱动对应的节点通常写在 rk3588s-evb.dts 或 rk3568-evb.dts 等板级文件中。

3.1 设备树语法快速回顾

设备树采用树形结构描述硬件,每个硬件设备对应一个节点(node),节点内包含若干属性(property)。基本语法规则如下:

  • 节点定义: node-name@unit-address { ... };,其中 unit-address 通常为寄存器基地址。
  • 属性赋值: property-name = <value>; 或 property-name = "string";。
  • 标签引用: 使用 &label 引用已定义的节点,便于在多个文件中扩展。
  • 包含文件: #include "rk3588.dtsi" 引入SoC级定义。
语法要点: 每个节点必须用分号结束;属性值支持32位整数、64位整数(<0x0 0x10000000>)、字符串、字节数组([01 02 03])和 phandle 引用。
设备树节点结构示例 / (根节点) soc@ff000000 i2c@ff3c0000 sensor@48 节点属性示例: compatible = "bosch,bmp280"; // 兼容性匹配 reg = <0x48>; // I2C设备地址 interrupt-parent = <&gpio1>; // 中断控制器

3.2 compatible属性:驱动与硬件的匹配桥梁

compatible 属性是设备树中最关键的属性之一,它决定了内核在启动时应该为哪个设备节点加载哪个驱动。其值通常为 "厂商,型号" 格式的字符串。

compatible 值 对应驱动 匹配优先级
"bosch,bmp280" drivers/iio/pressure/bmp280.c 精确匹配
"st,lsm6ds3" drivers/iio/imu/st_lsm6ds3_core.c 精确匹配
"invensense,mpu6050" drivers/iio/imu/inv_mpu6050/inv_mpu_core.c 精确匹配
"generic,i2c-sensor" 通用I2C探测驱动 兜底匹配
常见错误: compatible 字符串拼写错误或大小写不一致是驱动无法加载的首要原因。务必与驱动源码中 of_match_table 定义的字符串完全一致。

在驱动代码中,匹配过程通过 of_match_table 实现:

// 驱动端匹配表定义
static const struct of_device_id bmp280_of_match[] = {
    { .compatible = "bosch,bmp280" },
    { .compatible = "bosch,bme280" },
    { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, bmp280_of_match);

// 平台驱动注册
static struct platform_driver bmp280_driver = {
    .probe  = bmp280_probe,
    .remove = bmp280_remove,
    .driver = {
        .name = "bmp280",
        .of_match_table = bmp280_of_match,
    },
};
module_platform_driver(bmp280_driver);

3.3 reg属性:地址空间与设备寻址

reg 属性用于描述设备在总线上的地址范围或设备地址。对于不同总线类型,reg 的含义不同:

  • I2C设备: reg 表示7位从设备地址,如 reg = <0x48>;。
  • SPI设备: reg 表示片选编号,如 reg = <0>; 表示CS0。
  • 内存映射设备: reg 包含基地址和长度,如 reg = <0xff3c0000 0x10000>;。
reg属性在不同总线下的含义 I2C 设备 reg = <0x48> 7位从设备地址 SPI 设备 reg = <0> 片选编号 (CS0) 内存映射设备 reg = <0xff3c0000 0x10000> 基地址 + 长度 RK平台注意事项: Sensor通常挂接在I2C或SPI总线上,reg值必须与硬件原理图/Schematic中的设备地址一致。

3.4 中断属性:中断资源绑定

中断属性用于将设备的中断请求线(IRQ)连接到中断控制器。RK平台通常使用GPIO作为中断源,通过 interrupt-parent 和 interrupts 属性描述。

属性 说明 示例
interrupt-parent 指定中断控制器节点(phandle) &gpio1
interrupts 中断号、触发类型 <RK_PB2 IRQ_TYPE_EDGE_FALLING>
interrupt-names 中断命名(可选) "sensor_irq"

RK平台常用的中断触发类型宏定义:

// 在 include/dt-bindings/interrupt-controller/irq.h 中定义
#define IRQ_TYPE_NONE          0
#define IRQ_TYPE_EDGE_RISING   1
#define IRQ_TYPE_EDGE_FALLING  2
#define IRQ_TYPE_LEVEL_HIGH    4
#define IRQ_TYPE_LEVEL_LOW     8

// RK平台GPIO中断宏(在 include/dt-bindings/pinctrl/rockchip.h 中)
#define RK_PA0  0
#define RK_PB2  8   // GPIO1_B2
#define RK_PC5  21  // GPIO1_C5
中断绑定示例: 一个I2C Sensor使用GPIO1_B2作为中断引脚,下降沿触发:
sensor@48 {
    compatible = "bosch,bmp280";
    reg = <0x48>;
    interrupt-parent = <&gpio1>;
    interrupts = <RK_PB2 IRQ_TYPE_EDGE_FALLING>;
};

3.5 pinctrl属性:引脚复用与配置

pinctrl 属性是RK平台设备树中最复杂的部分之一,它负责配置SoC引脚的复用功能(如GPIO、I2C、SPI、UART)以及电气特性(上下拉、驱动强度)。

pinctrl 配置通常包含三个要素:

  • pinctrl-names: 定义状态名称,如 "default"、"sleep"、"active"。
  • pinctrl-0、pinctrl-1: 对应各状态的引脚配置节点引用。
  • 引脚配置节点: 在 &pinctrl 节点下定义,描述具体引脚功能。
pinctrl 属性配置流程 sensor@48 pinctrl-names = "default" pinctrl-0 <&sensor_irq_pins> sensor_irq_pins rockchip,pins = <1 RK_PB2 0 &pcfg_pull_up> pinctrl 配置详解: rockchip,pins = <bank pin mux config>; bank : GPIO组编号 (0=GPIO0, 1=GPIO1, ...) pin : 引脚编号 (RK_PA0~RK_PD7) mux : 功能复用值 (0=GPIO, 1=I2C, 2=SPI, ...) config: 电气配置 (pcfg_pull_up, pcfg_pull_down, pcfg_pull_none)

完整的Sensor设备树节点示例(RK3588平台):

// 在 rk3588s-evb.dts 中
&i2c4 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&i2c4m2_xfer>;
    
    bmp280: pressure-sensor@48 {
        compatible = "bosch,bmp280";
        reg = <0x48>;
        interrupt-parent = <&gpio1>;
        interrupts = <RK_PB2 IRQ_TYPE_EDGE_FALLING>;
        pinctrl-names = "default";
        pinctrl-0 = <&sensor_irq_pins>;
        status = "okay";
    };
};

// 引脚配置在 pinctrl 节点中
&pinctrl {
    sensor {
        sensor_irq_pins: sensor-irq-pins {
            rockchip,pins = <1 RK_PB2 0 &pcfg_pull_up>;
        };
    };
};
避坑指南:
  • 确保 pinctrl-0 引用的节点名称与 &pinctrl 下定义的标签完全一致。
  • I2C总线的pinctrl配置(如 i2c4m2_xfer)通常已在 rk3588.dtsi 中定义,板级文件只需 pinctrl-0 = <&i2c4m2_xfer>; 引用即可。
  • Sensor的中断引脚必须配置为GPIO功能(mux=0),否则无法产生中断信号。

3.6 属性组合实战:Sensor节点完整解析

将上述所有属性组合到一个完整的Sensor设备树节点中,并说明每个属性的作用:

属性 值 作用说明
compatible "bosch,bmp280" 匹配驱动 bmp280.c
reg <0x48> I2C从设备地址 0x48
interrupt-parent &gpio1 中断控制器为 GPIO1
interrupts <RK_PB2 IRQ_TYPE_EDGE_FALLING> GPIO1_B2 下降沿触发中断
pinctrl-names "default" 定义状态名称
pinctrl-0 <&sensor_irq_pins> 引脚配置为上拉输入
status "okay" 启用设备节点
调试技巧: 在RK平台中,可以通过 /sys/firmware/devicetree/base/ 目录查看实际生效的设备树内容。使用 cat /proc/device-tree/ 下的对应节点文件,可以验证属性值是否正确传递。