0. 本篇要解决什么问题

工业机器人和智能相机的外设开发,难点不只是“让一个节点出现在 /dev 下”,而是同时保证实时链路、相机稳定性、待机功耗和 BSP 可维护性。

本篇给出一条可落地的分层路径:Linux 负责真实硬件控制与标准设备模型,Hexagon 负责可卸载的帧处理,应用通过 V4L2、SocketCAN、IIO 与 FastRPC 组合能力。


1. 先建立正确的驱动边界

1.1 三类外设,三种 Linux 子系统

外设 首选 Linux 框架 用户态接口 项目关键点
I²C 传感器、EEPROM、IO 扩展器 I²C core + regmap + IIO / hwmon / input IIO sysfs、/dev/iio、hwmon、input 中断、量程、供电时序、总线恢复
SPI ADC、IMU、编码器前端、FPGA SPI core + regmap + IIO / MTD / 自定义驱动 IIO、MTD、专用字符设备 mode、bits-per-word、DMA 阈值、片选时序
CAN-FD 控制器/收发器 CAN networking + SocketCAN canX、CAN_RAW socket 位定时、错误帧、Bus-Off、时间戳
MIPI CSI-2 相机 V4L2 + Media Controller + CAMSS / ISP /dev/video、media graph 电源、CSI lane、sensor mode、buffer 生命周期

不要把协议栈重复实现到应用层。CAN-FD 应进入 SocketCAN;连续采样数据优先进入 IIO;相机走 V4L2 media graph。这样可直接复用诊断工具、权限模型、时间戳和上游生态

2. 板级准备:先把硬件事实写成清单

在修改 Device Tree 前,依据原理图和 BSP 的 board DTS,完成下面的“外设合同”。它能避免大量“驱动绑定了却没有数据”的问题。

项目 I²C/SPI CAN-FD MIPI 摄像头
物理连线 控制器、pinctrl、地址/片选、IRQ 控制器、收发器 EN/STB、CANH/CANL、120 Ω 终端 CSI port、lane 数、时钟、reset/pwdn、I²C 控制总线
电源 VDD/VIO、enable GPIO、上电延迟 控制器域与收发器电源、待机脚 AVDD/DVDD/IOVDD、时钟稳定时间、下电顺序
时钟 SPI 最大 SCLK、传感器 ODR 标称/数据相位时钟源 MCLK、CSI PHY、传感器 PLL
软件归属 IIO/hwmon/input 或专用子系统 SocketCAN + transceiver 控制 sensor subdev + CAMSS/ISP + V4L2
验收指标 IRQ、采样率、丢样率 error counter、Bus-Off、恢复 首帧时间、帧率、丢帧、恢复

3. I²C / SPI:从“能读寄存器”到可维护驱动

3.1 Device Tree 的最小职责

DTS 描述硬件存在、连接方式和不可在运行时改变的属性,不应承载业务策略。典型信息包括控制器 pinctrl、设备地址/片选、compatible、IRQ、regulator、reset GPIO、时钟与固定安装方向。

&qup_i2c5 {
    status = "okay";
    imu@68 {
        compatible = "vendor,imu123";
        reg = <0x68>;
        interrupt-parent = <&tlmm>;
        interrupts = <42 IRQ_TYPE_LEVEL_LOW>;
        vdd-supply = <&vreg_sensor_3p3>;
        vddio-supply = <&vreg_sensor_1p8>;
        reset-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>;
        status = "okay";
    };
};

&qup_spi3 {
    status = "okay";
    adc@0 {
        compatible = "vendor,adc456";
        reg = <0>;
        spi-max-frequency = <12000000>;
        interrupt-parent = <&tlmm>;
        interrupts = <58 IRQ_TYPE_EDGE_RISING>;
        status = "okay";
    };
};

示例名称仅为演示,必须对照当前 BSP 的 binding 文档和 DTSI。

3.2 驱动实现的推荐顺序

  1. 优先使用上游或 BSP 现有驱动:仅地址、GPIO、供电时序不同,优先 DTS 适配,不复制“近似驱动”。

  2. 寄存器访问使用 regmap:统一缓存、位操作、调试和总线传输。

  3. 进入正确子系统:连续采样传感器优先 IIO;健康信息优先 hwmon;按键、霍尔开关等事件可考虑 input。

  4. 中断优于高频轮询:IRQ 线程只做最少工作;批量读取与时间戳交由 IIO buffer / 工作队列。

  5. 电源管理是功能的一部分:实现 runtime PM,停流时关闭采样或进入 low-power mode,并验证恢复后的寄存器状态。

3.3 首轮调试命令

# 实验室确认地址与总线;量产逻辑不要依赖扫描。
i2cdetect -y 5
i2ctransfer -y 5 w1@0x68 0x75 r1

# SPI 绑定及 IIO 数据
ls -l /sys/bus/spi/devices/
dmesg | grep -Ei 'spi|iio|imu'
iio_info
cat /sys/bus/iio/devices/iio:device*/name

I²C NACK 不一定是地址错误,也可能是 VIO 未上电、reset/pwdn 极性错误、上电延迟不足或 pinmux 冲突。SPI 读回全 0xff / 0x00 时,优先检查 CPOL/CPHA、片选极性、bits-per-word 与 MISO 电平域。


4. CAN-FD:使用 SocketCAN,而不是自建字符设备协议

CAN-FD 在 Linux 中是网络设备。控制器驱动注册 canX,应用通过 PF_CAN / CAN_RAW socket 收发;iproute2can-utils、ROS 2 bridge 和抓包工具均可复用。

若载板挂接外置 CAN-FD 控制器,通常通过 SPI 接入,驱动还要控制收发器的 standby / enable GPIO。若平台已有 CAN 控制器,重点是 pinctrl、时钟、收发器与 DTS 配置。不要假设任意 IQ 载板都引出了同一控制器实例;请以原理图和 BSP 为准。

# 500 kbit/s 仲裁相位 + 2 Mbit/s 数据相位:仅为示例。
ip link set can0 down
ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on \
    berr-reporting on restart-ms 100
ip link set can0 up
ip -details -statistics link show can0
candump -e -x can0
cansend can0 123##31122334455667788

restart-ms 是否适合产品,取决于安全策略:普通遥测总线可以自动恢复;涉及机器人安全状态的总线,Bus-Off 后通常应上报故障、进入受控状态,并由安全状态机决定是否重新使能。

工业机器人要点:核对双端 120 Ω 终端、隔离收发器、共模范围、地参考和线束屏蔽;按系统设计计算仲裁/数据相位采样点;持续采集 TX/RX error counter、error passive、Bus-Off、重启次数和丢帧计数;相机、编码器和 CAN 融合时统一单调时钟/硬件时间戳策略。


5. MIPI 摄像头:Linux 负责采集,Hexagon 负责低功耗处理

5.1 为什么不能把“摄像头驱动放到 Hexagon”

典型 Qualcomm Linux BSP 中,摄像头传感器以 V4L2 sub-device 表达,CSI 接收器、CAMSS/ISP 和 video node 通过 Media Controller 形成图。sensor 的 I²C 配置、regulator、MCLK、reset/pwdn、CSI PHY 与 buffer queue 依赖 Linux 相机栈和 BSP 专有组件。

Hexagon 的正确位置是算法数据面:ROI 裁切、色彩转换、缩放、帧差、运动检测、质量统计、事件筛选和 NPU 前处理。它不应接管 CSI-2 sensor 的 probe、stream on/off 或 V4L2 内核 buffer 生命周期;该边界能避免电源域、缓存一致性和相机 vendor stack 被双重控制。

5.2 推荐实现:V4L2 DMABUF + FastRPC + 事件唤醒

  1. Linux camera service 使用 V4L2 配置 sensor mode,申请多缓冲队列;buffer 使用 DMA-BUF 在内核/用户态组件间传递。

  2. 应用服务 取得帧描述符与元数据(时间戳、stride、format、sequence),不复制整帧到普通堆内存。

  3. FastRPC client 将共享缓冲区句柄、尺寸和算法参数传递给 Hexagon 动态库;DSP 只读输入帧,或写入独立输出/metadata buffer。

  4. Hexagon worker 做轻量预处理与事件判断;仅在检测到目标、异常或达到上报周期时返回小型 metadata/ROI。

  5. Linux/ROS 2 节点 决定是否启动重模型、NPU 推理、录像、CAN 告警或网络上报。

关键不在于“每帧都送 DSP”,而是减少 DDR 往返、避免 CPU copy,用事件而非持续全分辨率处理唤醒重负载任务

5.3 缓冲区与同步规则

规则 工程含义
明确 buffer 所有权 每帧必须有唯一生产者、消费者完成条件与回收者;不能把 V4L2 buffer 当永久内存。
显式同步 跨 CPU/DSP/ISP 使用 DMA-BUF 时,按 BSP 接口处理 fence、cache 同步和 map/unmap。
元数据随帧走 帧号、单调时间戳、曝光/增益、格式和 ROI 坐标必须与 buffer 绑定。
限制处理预算 DSP worker 需要最大队列深度和超时策略;预览积压时丢弃旧帧通常优于增加延迟。
CPU fallback FastRPC/DSP 不可用或共享 buffer 导入失败时,降级到 CPU 路径并上报健康状态。

5.4 相机调试顺序

# 1) 确认 sensor -> CSI -> ISP/video node 链路。
media-ctl -p

# 2) 检查 V4L2 能力、格式和帧率。
v4l2-ctl -d /dev/video0 --all
v4l2-ctl -d /dev/video0 --list-formats-ext

# 3) 短时采集验证,再接 ROS 2 / DSP 算法。
v4l2-ctl -d /dev/video0 --stream-mmap=4 --stream-count=120 --stream-to=/dev/null

# 4) 检查 sensor、CSI、CAMSS/ISP、IOMMU 错误。
dmesg -w | grep -Ei 'camera|camss|csi|isp|i2c|iommu'

推荐定位顺序:供电/时钟 → I²C probe → sensor ID → media link → CSI 错误计数 → 首帧 → 连续采集 → buffer 导入 → DSP 算法。首帧没有稳定前,不要调优 Hexagon 算法。


6. MIPI 到 Hexagon 的低功耗处理流程

实际 FastRPC 方法名、DSP domain 与 buffer-import API 以当前 Qualcomm BSP / Hexagon SDK 为准。

7. 推荐的代码组织

peripheral-stack/
├── dts/                       # 板级 overlay / patch,与原理图版本对应
├── kernel/                    # 必要的 I2C/SPI/CAN 驱动补丁
├── userspace/
│   ├── camera-service/        # V4L2、DMA-BUF、帧元数据、健康检查
│   ├── can-service/           # SocketCAN、协议解析、Bus-Off 状态机
│   ├── sensor-service/        # IIO 采集、校准、时间戳
│   └── dsp-client/            # FastRPC client、buffer 导入、降级策略
├── hexagon/                   # DSP 算法库;不放 sensor kernel driver
├── ros2/                      # image/can/sensor bridge 与 diagnostics
└── tests/                     # 台架回归、长稳、异常注入

8. 验收清单:不要只验证“启动成功”

I²C / SPI

  • 冷启动、热复位、反复 suspend/resume 后均能 probe 与采样。
  • IRQ 频率、采样率、时间戳和丢样计数在目标负载下符合预期。
  • NACK、IRQ 卡死、电源抖动时,日志与健康状态可定位。
  • runtime PM 后,寄存器、校准状态和数据通路正确。

CAN-FD

  • 标称/数据相位速率、BRS、终端和收发器待机脚经过台架验证。
  • error warning、error passive、Bus-Off 与恢复策略均有记录和测试。
  • 长时间高负载下无异常重启,诊断计数持续采集。
  • 安全相关控制帧与普通遥测帧在状态机和故障策略上明确隔离。

MIPI + Hexagon

  • 冷启动首帧、连续运行、停流再开流、异常恢复均通过。
  • 采集到 DSP 无额外整帧 CPU copy,buffer 生命周期有可追踪日志。
  • DSP 队列深度、处理时延、事件触发率和 fallback 次数均可观测。
  • DSP/相机服务失败时,ROS 2 节点收到明确健康状态,不把陈旧帧当实时数据。
  • 在目标温度、供电和 CPU/NPU 负载下完成产品要求时长的稳定性测试。
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐