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 的完整链路:
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等,需查阅数据手册。