传感器驱动与数据质量¶
传感器驱动的职责不只是“读出几个寄存器”。它必须把硬件产生的字节转换成带有正确单位、方向、时间和健康状态的数据,并在总线或器件异常时给上层明确结果。

驱动的数据管线¶
典型过程包括:
- 识别总线和器件实例;
- 读取身份寄存器;
- 复位器件并等待规定时间;
- 写入量程、滤波、输出速率和中断配置;
- 验证关键寄存器是否生效;
- 在数据就绪事件或计划周期读取样本;
- 检查传输状态和样本完整性;
- 解析字节序和有符号数;
- 换算为统一物理单位;
- 应用传感器方向与校准;
- 记录采样时间、实例和错误状态;
- 发布给状态估计或其他消费者。
任何一步失败都不能静默地把零值或旧值伪装成新样本。
总线操作需要事务边界¶
SPI设备¶
串行外设接口(SPI,Serial Peripheral Interface)设备通常共享时钟和数据线,通过独立片选区分。
核对:
- SPI模式;
- 最大时钟;
- 读写位定义;
- 寄存器地址宽度;
- 片选建立和保持时间;
- 连续读取规则;
- 多字节顺序;
- 总线锁和DMA缓冲区。
错误片选可能让两个设备同时驱动总线。提高总线频率也可能只在短线或特定温度下工作。
I²C设备¶
内部集成电路总线(I²C,Inter-Integrated Circuit)通过地址区分设备。
核对:
- 7位或其他地址形式;
- 上拉电阻与总线电压;
- 时钟速率;
- 时钟延展;
- 重复起始;
- 超时;
- 总线被设备拉低后的恢复。
扫描到地址只证明某个设备响应,不能证明型号、配置和数据正确。
从原始码到物理量¶
以三轴角速度为例:
必须明确:
- 原始位宽和符号;
- 每位对应的量值;
- 度每秒还是弧度每秒;
- 右手系还是其他约定;
- 轴交换和正负号;
- 饱和值;
- 无效值。
单位错误可能让数值看起来“在变化”,却完全无法进入正确控制计算。
时间戳放在哪里¶
常见时间点包括:
- 物理采样时刻;
- 数据就绪中断时刻;
- 总线读取开始或结束时刻;
- 驱动发布时刻;
- 上层消费时刻。
状态估计更关心测量实际对应的物理时刻,而不是消息最终发布的时刻。若器件内部存在先入先出缓冲区(FIFO,First In First Out),还要根据样本顺序、输出速率和读取延迟重建每个样本的时间。
数据就绪与轮询¶
数据就绪中断可以减少无效轮询并提供更稳定的采样时刻,但需要验证:
- 引脚和边沿配置;
- 中断是否丢失或重复;
- 中断频率;
- 读取能否在下一批数据到达前完成;
- FIFO溢出行为;
- 中断故障后的降级策略。
没有数据就绪信号时可以轮询,但必须检测重复样本和样本年龄。
校准不是驱动常数¶
应区分:
- 器件固定比例和寄存器定义;
- 板级方向;
- 单台设备的偏置和比例校准;
- 温度补偿;
- 运行时估计的偏差。
把单台设备的校准值写死在通用驱动里,会让同型号其他设备继承错误参数。校准数据应绑定设备实例、硬件版本和有效条件。
滤波边界¶
传感器内部、驱动、状态估计器和控制器都可能有滤波。每级都要记录:
- 类型;
- 截止频率;
- 采样率;
- 相位或群延迟;
- 初始化状态;
- 参数变化时的状态处理;
- 是否影响故障检测。
重复滤波可能显著增加延迟。不能只根据曲线更平滑判断滤波更好。
健康状态不能只有“在线”¶
建议至少统计:
| 指标 | 用途 |
|---|---|
| 通信错误数 | 识别总线或连接问题 |
| 连续失败数 | 触发超时或重启 |
| 样本年龄 | 识别旧数据 |
| 更新率 | 识别降频和丢样 |
| FIFO溢出 | 识别处理不及时 |
| 饱和次数 | 识别量程不足 |
| 温度范围 | 识别超出补偿边界 |
| 一致性检查 | 比较冗余传感器或物理约束 |
| 重置次数 | 识别器件反复失效 |
“设备能返回身份值”只表示通信的第一步成功。
冗余传感器¶
多传感器系统还需要明确:
- 实例编号是否稳定;
- 谁是主传感器;
- 切换条件;
- 切换时坐标和校准是否一致;
- 故障隔离是否会来回抖动;
- 日志能否看出当前数据来源;
- 一个总线故障是否会同时影响多个实例。
两颗传感器共用同一供电或总线,并不构成完整独立冗余。
驱动验证顺序¶
- 主机端测试解析、缩放和边界;
- 用记录数据或虚拟总线重放;
- 在开发板上读取身份和配置寄存器;
- 验证静止偏置、六面方向和时间戳;
- 制造断线、超时、错误身份和饱和;
- 测量更新率、抖动和CPU占用;
- 验证重启、重新探测和故障上报;
- 与参考仪器或已知输入比较;
- 再接入状态估计器;
- 最后进入拆桨整机测试。
PX4 v1.17.0的驱动追踪示例¶
以FMUv5板级目标中的一个惯性传感器分支为例:
- 打开
boards/px4/fmu-v5/init/rc.board_sensors; - 找到
ver hwtypecmp对硬件版本的判断; - 其中一个分支启动
icm42688p -s -R 2 -q start,另一个分支启动icm20602; -s、-R 2和-q的具体含义必须回到该版本驱动的命令帮助与源码确认;- 进入
src/drivers/imu/invensense/icm42688p/; - 从模块入口找到总线对象、设备标识检查、寄存器配置、FIFO读取和发布对象;
- 在
src/drivers/imu/invensense/icm42688p/CMakeLists.txt和相关Kconfig中确认驱动进入构建; - 再从发布的
sensor_accel、sensor_gyro或FIFO主题追踪到sensors模块与估计器。
可使用:
rg "icm42688p" boards/px4/fmu-v5 src/drivers/imu
rg "sensor_accel|sensor_gyro" src/drivers/imu/invensense/icm42688p
在真实FMUv5兼容硬件上验证时必须拆除螺旋桨,并先确认该硬件版本确实使用对应器件。控制台中的典型只读检查为:
通过标准不是“命令有输出”,而是设备实例、更新率、错误计数、温度、轴方向和静止量级符合该板卡与安装条件。若目标硬件走icm20602分支,则不能强行启动icm42688p完成示例。
检查理解¶
- 为什么读取到寄存器值不等于驱动完成?
- 传感器时间戳为什么不能简单使用消息发布时间?
- 为什么单台设备校准值不应写进通用驱动?
- 两颗同总线传感器为什么不构成完整独立冗余?
- “在线”状态为什么不足以描述传感器健康?