4. Sensor 设备树节点编写:以加速度计为例

设备树(Device Tree)是 RK 平台下 Sensor 驱动与硬件描述解耦的核心机制。一个完整、规范的设备树节点,能够使驱动在无需修改代码的情况下适配不同板级设计。本节以 ST 微电子 LIS3DH 三轴加速度计为例,详细讲解设备树节点的编写方法,涵盖供电、中断、I2C 地址等关键属性。

实践前提:本节假设 Sensor 挂接在 I2C 总线(如 i2c5)上,使用 1.8V 数字供电、3.3V 模拟供电,且支持电平触发中断。实际项目中请根据 Sensor 数据手册和原理图调整参数。

4.1 设备树节点完整结构

一个标准的加速度计设备树节点,通常包含以下层级与属性:

  • 节点名称与地址:使用 lis3dh@18 格式,其中 18 为 7 位 I2C 地址(0x18)的十进制表示。
  • compatible:驱动匹配字符串,格式为 "st,lis3dh"。
  • reg:I2C 从设备地址。
  • 中断属性:指定中断引脚、触发类型。
  • 供电属性:通过 vdd-supply 和 vddio-supply 引用 regulator 节点。
  • mount-matrix:安装方向矩阵,用于坐标对齐。
/* 完整设备树节点示例:i2c5 总线下的 LIS3DH 加速度计 */
&i2c5 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&i2c5m0_xfer>;

    lis3dh: accelerometer@18 {
        compatible = "st,lis3dh";
        reg = <0x18>;
        interrupt-parent = <&gpio1>;
        interrupts = <RK_PB2 IRQ_TYPE_EDGE_RISING>;
        vdd-supply = <&vcc3v3_sys>;       /* 模拟供电 3.3V */
        vddio-supply = <&vcc1v8_sensor>;   /* 数字 I/O 供电 1.8V */
        st,drdy-int-pin = <1>;             /* 使用 INT1 引脚输出数据就绪 */
        mount-matrix = "0", "1", "0",
                       "-1", "0", "0",
                       "0", "0", "1";
        status = "okay";
    };
};
关键点:interrupts = <RK_PB2 IRQ_TYPE_EDGE_RISING> 中的 RK_PB2 是 RK 平台 GPIO 宏,表示 GPIO1_B2(即 GPIO1 组的第 10 脚)。IRQ_TYPE_EDGE_RISING 表示上升沿触发,适用于 LIS3DH 的数据就绪中断。

4.2 供电属性详解

Sensor 供电通常分为 模拟电源(vdd-supply) 和 数字 I/O 电源(vddio-supply)。在 RK 平台中,这些属性通过 phandle 引用已定义的 regulator 节点。

属性名 对应电源域 典型电压 作用
vdd-supply 模拟核心供电 2.4V ~ 3.6V 为 Sensor 内部 ADC、MEMS 模拟电路供电
vddio-supply 数字 I/O 供电 1.71V ~ 3.6V 为 I2C/SPI 接口、中断输出、寄存器接口供电

在驱动 probe 阶段,内核会按顺序调用 regulator_get 获取这些供电,并在 suspend/resume 中动态开关以降低功耗。如果供电节点缺失,驱动可能无法正确初始化或产生异常电流。

常见错误:部分开发者将 vdd-supply 和 vddio-supply 指向同一个 regulator,但实际硬件中模拟与数字供电可能来自不同 LDO。务必核对原理图,避免供电串扰导致 Sensor 精度下降。

4.3 中断属性配置

中断属性决定了 Sensor 与 SoC 之间的异步通信方式。LIS3DH 支持两个可编程中断引脚(INT1/INT2),设备树中通过 interrupts 和 st,drdy-int-pin 配合使用。

/* 中断属性分解 */
interrupt-parent = <&gpio1>;          /* 中断控制器:GPIO1 */
interrupts = <RK_PB2 IRQ_TYPE_EDGE_RISING>;
/* RK_PB2 = GPIO1_B2 = 32 + 8 + 2 = 42 (GPIO 子编号) */
/* IRQ_TYPE_EDGE_RISING = 上升沿触发 */

常见中断触发类型对比:

宏定义 触发方式 适用场景
IRQ_TYPE_EDGE_RISING 上升沿触发 数据就绪、单次唤醒
IRQ_TYPE_EDGE_FALLING 下降沿触发 阈值比较、运动检测
IRQ_TYPE_LEVEL_HIGH 高电平触发 持续中断状态指示
IRQ_TYPE_LEVEL_LOW 低电平触发 低功耗唤醒(需电平保持)
选型建议:对于加速度计的数据读取,推荐使用 IRQ_TYPE_EDGE_RISING,因为 LIS3DH 在数据就绪时 INT1 引脚会从低变高,读取数据后自动拉低,边缘触发可避免电平模式下的重复中断。

4.4 mount-matrix:安装方向矩阵

由于 Sensor 在 PCB 上的安装方向可能与设备坐标系不一致,设备树通过 mount-matrix 属性提供 3x3 旋转矩阵,驱动读取后对原始数据进行坐标变换。

/* mount-matrix 格式:9 个字符串,按行优先排列 */
mount-matrix = "0", "1", "0",   /* X 轴映射到设备 Y 轴 */
               "-1", "0", "0",  /* Y 轴映射到设备 -X 轴 */
               "0", "0", "1";   /* Z 轴保持不变 */

矩阵含义:

  • 每一行对应 Sensor 的一个输出轴(X, Y, Z)。
  • 每一列对应设备坐标系的一个轴。
  • 值为 1 表示正方向映射,-1 表示反方向映射,0 表示无映射。
验证方法:将设备平放桌面,读取原始数据。若 Z 轴读数接近 +1g(约 9.8 m/s²),X/Y 接近 0,则矩阵正确。若 Z 轴为 -1g,则需将 Z 轴映射值改为 "-1"。

4.5 设备树节点与驱动匹配流程

以下 SVG 流程图展示了从设备树解析到驱动 probe 的完整链路:

设备树节点与驱动匹配流程 设备树节点 → 驱动匹配流程 设备树源文件 (.dts) 设备树二进制 (.dtb) Bootloader 加载 DTB 到内存 内核 OF 子系统解析 DTB I2C 总线驱动匹配 compatible Sensor 驱动 probe 执行 关键匹配条件 1. compatible 字符串一致 2. reg 地址与硬件一致 3. 供电 regulator 可用 4. 中断 GPIO 未被占用

4.6 常见设备树编写错误与排查

错误类型 现象 排查方法
compatible 不匹配 驱动 probe 未调用 检查 /sys/bus/i2c/devices/5-0018/uevent 中的 OF_NAME
reg 地址错误 I2C 探测失败 使用 i2cdetect -y 5 确认设备地址
供电 regulator 未就绪 probe 返回 -EPROBE_DEFER 查看 dmesg | grep regulator 确认供电时序
中断 GPIO 冲突 中断无法注册 检查 /sys/kernel/debug/gpio 确认引脚状态
mount-matrix 格式错误 数据坐标异常 读取原始数据与预期方向对比
调试技巧:在驱动 probe 函数中添加 dev_info(dev, "OF node: %pOF\n", dev->of_node);,可打印当前匹配的设备树节点路径,快速确认设备树是否被正确解析。

4.7 本章小结

设备树节点是 Sensor 驱动与硬件平台之间的“契约”。一个完整的加速度计节点应包含:

  • 基础属性:compatible、reg、status。
  • 供电属性:vdd-supply 和 vddio-supply,分别对应模拟与数字电源。
  • 中断属性:interrupt-parent、interrupts,配合触发类型定义。
  • 方向校准:mount-matrix 确保坐标系对齐。
  • 芯片专用属性:如 st,drdy-int-pin 等,需查阅数据手册。