DriveOS/SIPL 相机模组适配

第1篇|从零搭骨架:DriveOS/SIPL 相机模组适配需要哪些文件?

目标:看完后,知道适配一个新相机模组时该创建/修改哪些文件、每类文件负责什么、验证路径是什么。

开场:不要一上来就改寄存器,先把代码架构搭对

很多工程师第一次接触 DriveOS/SIPL 相机适配,会直接问:

sensor 初始化寄存器表写在哪里?

这个问题不算错,但顺序错了。

在 SIPL 里,一个相机模组能跑起来,至少需要三类东西先对上:

  1. Query 配置:告诉 SIPL "这个平台/模组/传感器是谁";
  2. devblk 驱动库:告诉 SIPL "具体生命周期怎么执行";
  3. TransportLink/SerDes 初始化:告诉系统"远端 serializer/deserializer 链路怎么拉起来"。

如果这三层没搭好,寄存器表写得再认真,也可能根本不会被执行。

一、SIPL 适配的最小文件地图

ISX031 + MAX96717F + MAX96712 为例,一个可维护的适配通常包含以下文件/目录:

text 复制代码
nvsipl/
  query/
    database/
      isx031_max96717f/
        isx031.json
        isx031_max96717f.json
        isx031_max96717f_platform.json
    database/
      serdes/
        max96712_max96717f.json 或已有 serdes 配置

  devblk/
    cameramodule/
      MAX96712cameramodule/
        CNvMTransportLink_Max96712_96717.cpp
        isx031_max96717f/
          CNvMMAX96712_96717F_ISX031.cpp
          cdi_isx031.c
          cdi_isx031.h
          Makefile 或构建入口

你可以把它理解为:
#mermaid-svg-zA9CX5KKOYx6Vboj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zA9CX5KKOYx6Vboj .error-icon{fill:#552222;}#mermaid-svg-zA9CX5KKOYx6Vboj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zA9CX5KKOYx6Vboj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zA9CX5KKOYx6Vboj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zA9CX5KKOYx6Vboj .marker.cross{stroke:#333333;}#mermaid-svg-zA9CX5KKOYx6Vboj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zA9CX5KKOYx6Vboj p{margin:0;}#mermaid-svg-zA9CX5KKOYx6Vboj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zA9CX5KKOYx6Vboj .cluster-label text{fill:#333;}#mermaid-svg-zA9CX5KKOYx6Vboj .cluster-label span{color:#333;}#mermaid-svg-zA9CX5KKOYx6Vboj .cluster-label span p{background-color:transparent;}#mermaid-svg-zA9CX5KKOYx6Vboj .label text,#mermaid-svg-zA9CX5KKOYx6Vboj span{fill:#333;color:#333;}#mermaid-svg-zA9CX5KKOYx6Vboj .node rect,#mermaid-svg-zA9CX5KKOYx6Vboj .node circle,#mermaid-svg-zA9CX5KKOYx6Vboj .node ellipse,#mermaid-svg-zA9CX5KKOYx6Vboj .node polygon,#mermaid-svg-zA9CX5KKOYx6Vboj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zA9CX5KKOYx6Vboj .rough-node .label text,#mermaid-svg-zA9CX5KKOYx6Vboj .node .label text,#mermaid-svg-zA9CX5KKOYx6Vboj .image-shape .label,#mermaid-svg-zA9CX5KKOYx6Vboj .icon-shape .label{text-anchor:middle;}#mermaid-svg-zA9CX5KKOYx6Vboj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zA9CX5KKOYx6Vboj .rough-node .label,#mermaid-svg-zA9CX5KKOYx6Vboj .node .label,#mermaid-svg-zA9CX5KKOYx6Vboj .image-shape .label,#mermaid-svg-zA9CX5KKOYx6Vboj .icon-shape .label{text-align:center;}#mermaid-svg-zA9CX5KKOYx6Vboj .node.clickable{cursor:pointer;}#mermaid-svg-zA9CX5KKOYx6Vboj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zA9CX5KKOYx6Vboj .arrowheadPath{fill:#333333;}#mermaid-svg-zA9CX5KKOYx6Vboj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zA9CX5KKOYx6Vboj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zA9CX5KKOYx6Vboj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zA9CX5KKOYx6Vboj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zA9CX5KKOYx6Vboj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zA9CX5KKOYx6Vboj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zA9CX5KKOYx6Vboj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zA9CX5KKOYx6Vboj .cluster text{fill:#333;}#mermaid-svg-zA9CX5KKOYx6Vboj .cluster span{color:#333;}#mermaid-svg-zA9CX5KKOYx6Vboj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zA9CX5KKOYx6Vboj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zA9CX5KKOYx6Vboj rect.text{fill:none;stroke-width:0;}#mermaid-svg-zA9CX5KKOYx6Vboj .icon-shape,#mermaid-svg-zA9CX5KKOYx6Vboj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zA9CX5KKOYx6Vboj .icon-shape p,#mermaid-svg-zA9CX5KKOYx6Vboj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zA9CX5KKOYx6Vboj .icon-shape .label rect,#mermaid-svg-zA9CX5KKOYx6Vboj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zA9CX5KKOYx6Vboj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zA9CX5KKOYx6Vboj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zA9CX5KKOYx6Vboj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 平台配置 platform json
模块配置 module json
传感器配置 sensor json
SerDes 配置
devblk driver so
CameraModule 生命周期
TransportLink 链路初始化
Sensor CDI

二、Query 文件:让平台"被找到"

目的:让 nvsipl_camera --platform-config xxx 能找到你的平台。

通常需要填:

  • 平台名,例如 ISX031_MAX96717F_RGGB_CPHY_x4
  • 使用哪些 deserializer block;
  • 每个 block 下挂哪些 camera module;
  • 默认 link mask / module mask;
  • 目标 sensor/module 名称。

如果这里没配对,现象通常是:平台名解析失败,或者运行时根本没有走到你的驱动。

2)module json:声明 sensor + serializer + deserializer 拓扑

目的:告诉 SIPL 这个 camera module 由哪些设备组成。

通常需要填:

  • camera module 名称,例如 ISX031_MAX96717F_RGGB
  • sensor 名称,例如 ISX031
  • serializer 名称,例如 MAX96717F
  • deserializer 名称,例如 MAX96712
  • I2C 地址、广播地址、link id、port 等拓扑信息。

这层配错,常见现象是:driver 库能加载,但 serializer presence 或 translator 阶段失败。

3)sensor json:声明真实视频流属性

目的:告诉 SIPL 传感器输出的数据长什么样。

通常需要填:

  • 分辨率;
  • 帧率;
  • 输出格式,例如 YUV422 / RAW;
  • data type;
  • embedded line 数;
  • 是否启用 embedded data type;
  • trigger/sync 相关模式。

注意:对于黑盒模组,sensor json 不是"随便照抄已有 sensor"的地方。它必须和真实输出流一致。否则可能出现 VIDEO_LOCK 成功但 ICP 报错。

三、devblk driver:让 SIPL 能加载你的实现

Query 只告诉 SIPL "有什么设备",真正执行初始化的是 devblk driver so。

关键产物类似:

text 复制代码
libnvsipl_devblk_drv_isx031_max96717f.so

它内部通常包含:

  1. CameraModule 实现:CNvMMAX96712_96717F_ISX031.cpp
  2. TransportLink 实现:CNvMTransportLink_Max96712_96717.cpp
  3. Sensor CDI:cdi_isx031.c
  4. SerDes CDI:cdi_max96717f.c / cdi_max96712.c

CameraModule 文件要做什么?

它负责生命周期编排:

  • DetectModule():检测模组是否存在;
  • InitModule():初始化模块;
  • StartModule():启动数据流;
  • PostSensorInit():sensor init 后检查 link/video 状态。

对于黑盒模组,这里要决定一个核心策略:

是否把 sensor 当作可完全编程设备,还是把它当作 vendor-fixed 模组,只走 link-only 初始化。

四、TransportLink:真正拉起 MAX96717F/MAX96712 链路

TransportLink 是本项目最关键的执行层。

它通常负责:

  1. 检查 broadcast serializer 是否在线;
  2. 设置 translator A/B,让远端 I2C 地址可达;
  3. 配置 MAX96712/MAX96717F 的链路模式;
  4. 配置 pipeline / data type / mapping;
  5. 配置 FSYNC 或触发相关路径;
  6. 检查 GMSL2_LINK_LOCK
  7. 检查 PCLKDET
  8. 检查 VIDEO_LOCK

如果模组是厂商黑盒,还可能需要补充 vendor-specific serializer bring-up 序列。

五、Sensor CDI:不一定总是主角

在传统 sensor 适配中,cdi_xxx.c 里常常包含:

  • 读 model id;
  • 写默认寄存器;
  • 配置 mode;
  • start/stop streaming。

但在 vendor-fixed 模组中,sensor CDI 可能只需要保留接口,并对部分动作做 bypass/no-op。

原因是:

  • sensor 内部配置可能已由厂商固化;
  • 外部 I2C 不一定开放完整 sensor 编程面;
  • 成功标准应转移到 SerDes 链路和视频锁定。

这就是本系列后面会反复强调的 link-only 思维

六、适配新模组时的推荐创建顺序

建议不要从 driver 代码乱改,而按这个顺序搭:

  1. 创建/修改 query platform json,让平台名可被解析;
  2. 创建/修改 module json,明确 sensor/serializer/deserializer 拓扑;
  3. 创建/修改 sensor json,声明真实流属性;
  4. 确认 query so 能构建并被加载;
  5. 创建 devblk driver 目录与 CameraModule 框架;
  6. 接入 TransportLink,先跑通 presence/translator/link lock;
  7. 再处理 PCLKDET/VIDEO_LOCK;
  8. 最后处理 ICP/fps/drop 等业务层验证。

#mermaid-svg-0xODwsaxliWVhdbU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0xODwsaxliWVhdbU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0xODwsaxliWVhdbU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0xODwsaxliWVhdbU .error-icon{fill:#552222;}#mermaid-svg-0xODwsaxliWVhdbU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0xODwsaxliWVhdbU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0xODwsaxliWVhdbU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0xODwsaxliWVhdbU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0xODwsaxliWVhdbU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0xODwsaxliWVhdbU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0xODwsaxliWVhdbU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0xODwsaxliWVhdbU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0xODwsaxliWVhdbU .marker.cross{stroke:#333333;}#mermaid-svg-0xODwsaxliWVhdbU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0xODwsaxliWVhdbU p{margin:0;}#mermaid-svg-0xODwsaxliWVhdbU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0xODwsaxliWVhdbU .cluster-label text{fill:#333;}#mermaid-svg-0xODwsaxliWVhdbU .cluster-label span{color:#333;}#mermaid-svg-0xODwsaxliWVhdbU .cluster-label span p{background-color:transparent;}#mermaid-svg-0xODwsaxliWVhdbU .label text,#mermaid-svg-0xODwsaxliWVhdbU span{fill:#333;color:#333;}#mermaid-svg-0xODwsaxliWVhdbU .node rect,#mermaid-svg-0xODwsaxliWVhdbU .node circle,#mermaid-svg-0xODwsaxliWVhdbU .node ellipse,#mermaid-svg-0xODwsaxliWVhdbU .node polygon,#mermaid-svg-0xODwsaxliWVhdbU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0xODwsaxliWVhdbU .rough-node .label text,#mermaid-svg-0xODwsaxliWVhdbU .node .label text,#mermaid-svg-0xODwsaxliWVhdbU .image-shape .label,#mermaid-svg-0xODwsaxliWVhdbU .icon-shape .label{text-anchor:middle;}#mermaid-svg-0xODwsaxliWVhdbU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0xODwsaxliWVhdbU .rough-node .label,#mermaid-svg-0xODwsaxliWVhdbU .node .label,#mermaid-svg-0xODwsaxliWVhdbU .image-shape .label,#mermaid-svg-0xODwsaxliWVhdbU .icon-shape .label{text-align:center;}#mermaid-svg-0xODwsaxliWVhdbU .node.clickable{cursor:pointer;}#mermaid-svg-0xODwsaxliWVhdbU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0xODwsaxliWVhdbU .arrowheadPath{fill:#333333;}#mermaid-svg-0xODwsaxliWVhdbU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0xODwsaxliWVhdbU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0xODwsaxliWVhdbU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0xODwsaxliWVhdbU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0xODwsaxliWVhdbU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0xODwsaxliWVhdbU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0xODwsaxliWVhdbU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0xODwsaxliWVhdbU .cluster text{fill:#333;}#mermaid-svg-0xODwsaxliWVhdbU .cluster span{color:#333;}#mermaid-svg-0xODwsaxliWVhdbU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0xODwsaxliWVhdbU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0xODwsaxliWVhdbU rect.text{fill:none;stroke-width:0;}#mermaid-svg-0xODwsaxliWVhdbU .icon-shape,#mermaid-svg-0xODwsaxliWVhdbU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0xODwsaxliWVhdbU .icon-shape p,#mermaid-svg-0xODwsaxliWVhdbU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0xODwsaxliWVhdbU .icon-shape .label rect,#mermaid-svg-0xODwsaxliWVhdbU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0xODwsaxliWVhdbU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0xODwsaxliWVhdbU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0xODwsaxliWVhdbU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Query平台可见
拓扑描述正确
Driver可加载
SerDes链路打通
Video Lock成功
业务流稳定

七、本篇小结

如果你是陌生工程师,请先记住:

  1. SIPL 相机适配不是"只写一个 sensor 驱动";
  2. query 决定"系统如何认识你";
  3. devblk driver 决定"系统如何执行你";
  4. TransportLink 决定"链路能否真正打通";
  5. 黑盒模组下,sensor CDI 可能不是主路径。

本篇 checklist

  • 知道 query/platform/module/sensor json 分别负责什么
  • 知道 devblk driver so 中通常包含哪些代码文件
  • 知道为什么黑盒模组要优先看 TransportLink
  • 能按推荐顺序搭建一个新模组适配骨架

下篇预告

下一篇我们只讲 Query:

如何从 0 到 1 创建平台 json、module json、sensor json,让 nvsipl_camera 能识别你的新模组?

系列导航卡片

  • 当前进度:第 1/6 篇(文件骨架)
  • 下一篇:第2篇《Query 配置从 0 到 1:让平台名、模组和视频流被 SIPL 正确认识》
  • 本系列主线:文件骨架 → Query 配置 → devblk 驱动 → TransportLink 链路 → 部署验证 → 复盘方法论
相关推荐
Vaeeeeeee18 小时前
NVIDIA智能汽车技术实战营笔记——Alpamayo
自动驾驶·汽车·nvidia·nvidia智能汽车技术公开课·l4
XUHUOJUN4 天前
Azure Local GPU 部署与企业应用场景指南(下篇)
microsoft·架构·nvidia·azure local
XUHUOJUN4 天前
Azure Local GPU 部署与企业应用场景指南(上篇 )
windows·microsoft·架构·nvidia·azure local
avi91119 天前
[AI教做人]CinemachineCamera 各项调整配置参数入门 + Profiler
unity·游戏开发·camera·cinemachine·visual camera·镜头配置
菜地里的小菜鸟10 天前
Nvidia L20安装驱动(ubuntu 24.04)
nvidia·nvidial20安装驱动ubuntu2·nvidia 驱动安装
牛奶15 天前
AI 能赚钱了——但赚的不是你
人工智能·ai编程·nvidia
basketball6161 个月前
AI Infra 硬件体系与编程模型:17. CUDA编程基础:底层驱动 API 调用
人工智能·microsoft·nvidia·cuda
百度搜知知学社1 个月前
Relens大光圈单反相机高级版,拍出专业级光影质感
camera·lens·photography·portrait