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 引用。
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>;。
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节点下定义,描述具体引脚功能。
完整的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/ 下的对应节点文件,可以验证属性值是否正确传递。