Skip to content

近期开发复盘:从疑难问题到架构与验证闭环

近期整理了 21 篇技术文章,重点不是展示“最后怎么配置”,而是保留完整的问题解决过程:现场出现什么症状、最初判断哪里错了、证据怎样收敛、为什么做出这个架构选择、修复后又如何证明。

内容从多媒体框架、DMA-BUF、NPU、VINS、时间同步延伸到 MAVLink 与混合架构 CI。看似分散,实际都在回答同一个问题:怎样从一个模糊故障出发,建立可验证的证据链,并把一次修复沉淀成可复用的工程方法。

问题复盘优先阅读

现场症状容易做出的错误判断最终要追的根因文章
FP16 模型能跑,但不知道输入应该是什么类型根据模型名称直接硬编码 dtype模型精度、Runtime 输入与 NPU 计算精度混淆NPU 输入踩坑复盘
换成 DMA-BUF 后 CPU 仍然很高以为换接口就等于移除复制ROS、颜色转换、float32 物化和 Runtime 转换仍在NPU 输入踩坑复盘
has_sync=True,相机与 IMU 仍有固定偏差把链路在线当成端到端同步message stamp 没有统一到同一 time domain时间同步 QA 工程化
NTPSynchronized=yes,却找不到 NTP 校时流量只相信状态字段实际校时源可能是 PTP → PHC → phc2sysRTC、PTP 与真实校时源
CI 换源后 amd64 正常、arm64 仍失败继续更换同一套镜像地址两种架构对应不同 archive 拓扑混合架构 CI 的 APT 源
DMA-BUF fd 已发送,下游仍偶发读到污染帧认为 fd 传递完成就能立即复用buffer ownership、ACK 与复用时序不完整跨进程 DMA-BUF 所有权合同
CmaFree=0,看起来 1 GiB CMA 已耗尽直接扩容或杀进程kernel 开启 CMA_INACTIVE,统计字段不能直接代表 headroomRK3588 CMA 排障复盘
服务显示 active,下游仍无限重连继续增加重试和启动延迟配置组合无法生产 consumer 所需的数据Service Active 但未 Ready
CI job 被触发,脚本却因 fingerprint 未变退出认为只是一次无害空跑trigger 集与 artifact fingerprint 输入集合不一致CI Trigger 与 Fingerprint
模型能解密,但无法证明内容是批准版本把“解密成功”当完整性验证缺少内层 payload hash 与 lock file 合同模型资产完整性门禁
源码已修复,板端行为仍像旧版本继续修改算法代码package、资产、进程身份与 source commit 没有闭环发布包与源码追踪

文章地图

RK3588 高性能视觉

文章解决的问题
RK3588 高性能相机流水线如何建立 V4L2 → RGA → OpenCL → 算法/MPP 的单一生产主链
单一 Owner 与显式失败为什么生产链拒绝多 owner 和静默 CPU fallback,并如何保留可审计回滚
Rockit 与 MPP 对比分析完整多媒体管线与单独编解码该怎样选型
DMA-BUF Heaps 与 CMA分配接口、共享句柄和连续内存后端分别处在哪一层
RK3588 CMA 排障复盘CmaFree=0 为什么不是耗尽结论,以及 384/512 MiB 怎样做生产选择
跨进程 DMA-BUF 所有权合同SCM_RIGHTS 发送 fd 后,buffer 何时才能安全复用
RK3588 板端性能 A/B如何证明资源下降不是版本混用或功能缺失造成的
NPU 输入踩坑复盘FP16、DMA-BUF、CPU 热点、重复物化与 layout 漂移是怎样定位和修复的
RKNN 输入 dtype模型精度、Runtime 输入类型和 NPU 计算精度怎样区分

时间系统与 VIO

文章解决的问题
RK3588 与 PX4 高精度时间同步怎样用 PPS 共同事件估计跨时钟域 offset
时间同步 QA 工程化为什么 has_sync=True 不是端到端同步结论
相机与 IMU 时间戳语义固定 4ms/9ms 偏差为什么更像 PTS、曝光或 td 问题
VINS 直连灰度 DMA-BUF如何移除 ROS 图像复制,同时保留 IMU 与 odometry 接口

协议与工程交付

文章解决的问题
MAVLink wire type 与业务语义uint8_t byte 如何承载 signed dBm,extension 又如何守住长度边界
混合架构 CI 的 APT 源amd64 与 arm64 为什么必须对应不同 archive 拓扑
RTC、PTP 与真实校时源NTPSynchronized=yes 为什么不能证明 NTP 正在校时
RK3588 GPIO 编号计算怎样从 Bank、Group、Pin 推导 line offset 并在板端确认

疑难排障与交付门禁

文章解决的问题
Service Active 但未 Ready为什么进程存活不能证明数据链健康,以及怎样建立 readiness 验收
CI Trigger 与 Fingerprint如何让触发路径、source hash 与真实 artifact contract 保持一致
模型资产完整性门禁怎样同时证明模型已加密、可解密且内层内容匹配批准版本
发布包与源码追踪怎样证明板端真实运行的是目标源码、配置、模型和 package

架构选择索引

决策放弃的方案选择理由文章
相机 runtime 保持单一 owner多个采集节点各自拥有设备与 buffer pool避免设备争抢、时间语义分叉和恢复路径歧义单一 Owner 与显式失败
生产链能力不足时显式失败OpenCL 失败后静默切换 CPU防止服务看似健康但性能、延迟和热状态已经改变单一 Owner 与显式失败
Atlas 作为单一物理存储Atlas 与四对独立图像同时物化ROI view 能表达逻辑切片,不增加复制与 CMA 压力NPU 输入踩坑复盘
Layout 由 producer 进入 typed contractConsumer 通过宽高常量自行推断让几何变化在边界处失败,而不是静默输出错误结果NPU 输入踩坑复盘
实时 consumer 使用 Latest,关键阶段使用有界队列所有支路同步阻塞或无限积压过载策略可预测,慢 consumer 不拖死生产者单一 Owner 与显式失败
模型策略使用独立 CI gate把检查埋进完整工程 build失败更快、更清晰,资产规则长期可审计模型资产完整性门禁

1. Rockit 与 MPP:先分清层次,再谈选型

《Rockit 与 MPP 对比分析》首先澄清了一个常见误区:Rockit 和 MPP 不是简单的竞品关系。

  • MPP 位于编解码层,适合文件转码、单独编码或需要轻量集成的场景。
  • Rockit 位于完整多媒体管线层,覆盖 VI、VPSS、VENC、VO 等模块,并通过 Bind 和统一内存块组织数据流。
  • Rockit 的编解码能力仍建立在 MPP 之上,真正的差异是它是否帮应用管理采集、处理、编码、显示和跨模块内存。

这篇文章最重要的结论不是“哪个更强”,而是:选型取决于你要解决的是一个编解码问题,还是一条完整的视频管线。

对于 RK3588 上的摄像头、AI 前处理和编码场景,这个边界会直接影响内存搬运、DMA-BUF 共享、模块所有权与后续维护成本。

2. GPIO 编号:把命名规则变成公式

《RK3588 GPIO 编号计算指南》GPIO3_D4 这样的硬件命名拆成 Bank、Group、Pin 三部分:

text
Bank 内偏移 = Group 偏移 + Pin
全局编号 = Bank × 32 + Bank 内偏移

公式本身并不复杂,真正容易出错的是接口语义:libgpiod 通常接收的是某个 gpiochip 内部的 line offset,而不是全局编号。

因此,计算只是第一步,实际使用时还要通过 gpiodetectgpioinfo 确认 gpiochip 的注册顺序与 line 映射。这里体现的是嵌入式开发里很重要的习惯:公式负责建立模型,系统接口负责确认模型与当前设备一致。

3. PX4 时间同步:用同一个物理事件连接两个时钟域

《RK3588 与 PX4 飞控高精度时间同步》处理的是一个更隐蔽的问题:PX4 飞控与 RK3588 机载计算机拥有不同的时钟基准,传感器时间戳不能直接混用。

方案使用同一个 PPS 上升沿作为共同事件:

text
RK3588 时间 = PX4 时间 + offset
offset = RK3588 捕获 PPS 的时间 - PX4 记录 PPS 的时间

因为两端比较的是同一个硬件事件,串口传输延迟不会直接进入 offset;串口只负责把 PX4 已记录的事件时间带到 RK3588。随后再用 EMA 对 GPIO 中断延迟和晶振漂移带来的抖动做平滑。

这篇文章的核心不是某个滤波参数,而是同步设计的原则:先找到跨时钟域共同可见的事件,再围绕这个事件估计和维护偏移。

4. 这一批文章的共同方法

阶段Rockit / MPPRK3588 GPIOPX4 时间同步
划清边界编解码层与多媒体管线层全局编号与 chip 内偏移PX4 boot time 与 Linux monotonic time
建立模型模块、Bind 与内存关系Bank × 32 + Group + Pin本地时间 = 飞控时间 + offset
真实验证数据是否沿预期模块流转gpiodetect / gpioinfoPPS 捕获、时间戳与 offset 稳定性

这套方法可以复用到更多板端问题:不要从零散 API 开始堆代码,而是先明确谁拥有数据、边界在哪里、哪些量可以被观测。模型成立后,再用真实设备上的接口、时间戳或数据流完成闭环。

5. 工程环境延伸阅读

如果要补齐工程环境,可以继续阅读:

这 21 篇内容已经形成一套相互连接的阅读路径:从故障现场和错误假设开始,进入平台分层、相机/VINS 主链与架构选择,再落到时间语义、协议边界、CI 门禁和板端验证。后续新增内容也会继续优先记录“问题怎样解决”,而不是变成孤立的配置笔记。

最后更新于: