结论:原生相机链同时描述了 OS04C10 与 OX03C10 两套传感器,每路先探测 OS04C10、失败再回退 OX03C10。曝光闭环按 20 Hz、固定 dt=0.05 平滑目标灰度,检索范围只有当前模拟增益索引的 g-1..g+1,并且用三帧前的 EV 做反馈——所以状态消息里的曝光字段与随后提交的下一组寄存器值,不能不加帧延迟地视为同一时刻的物理测量。
两套传感器描述:不只是「读曝光的接口」
SensorInfo 同时承载探测地址、启动/I2C 表、RAW 格式、曝光范围/增益表、读出时间以及 ISP LUT;它不是仅有 getExposureRegisters() 的驱动接口。openSensor() 在每一路先尝试 OS04C10,再尝试 OX03C10,两个 sensors_init() 都失败才禁用该路。两种实现的 getSlaveAddress() 都把端口 0/1/2 映射为 0x6c/0x20/0x6c——新板的 I2C mux/线序不能只靠改传感器 ID 解决。
| 契约 | OS04C10 | OX03C10 |
|---|---|---|
| 分辨率/格式 | 2688×1520,RAW12,BGBG Bayer,out_scale=2 |
1928×1208,RAW12,GRGR Bayer,stride 另加 4 字节,顶部/底部额外行及 frame_offset=2 |
| MCLK / 探测 ID | 24 MHz,ID 0x5304 |
24 MHz,ID 0x5803 |
| 曝光范围 / EOF 偏移 | 2..2352 行,11 ms | 2..2016 行,14.697 ms |
| 模拟增益索引 | 0..40 | 0..54 |
| ISP | 黑电平、色彩矩阵、gamma、线性化、暗角 | 对应 OX 配置 |
探测都读寄存器 0x300a。两个必须注意的点:EOF 是 SOF + readout_time_ns 的推算值,不是独立硬件捕获;OS04C10 的 11 ms 在源码中注明来自日志估计。模拟增益方面,两者的物理增益表虽相同,寄存器编码不同,索引必须受各自 analog_gain_max_idx 限制。ISP 侧,prepare_gamma_lut() 将 65 个采样点打包为 64 项;这些校正表与具体镜头/传感器组合绑定。
探测供电、CSI 与 ISP 的真实耦合
sensors_init() 组装一次 Qualcomm CAM_SENSOR_PROBE_CMD:I2C 采用 fast mode(源码注释为 400 kHz),16 位寄存器地址和 16 位 ID 数据。探测包内嵌固定上电/下电序列:先设置电源/复位项,等待 1 ms;给 MCLK 写入 24 MHz,再等待 1 ms;释放复位后等待 34 ms,才执行探测。源文档提醒,源码对某些 power_seq_type 仍保留「clock??」等不确定注释,不能把整数直接当作可投板的稳压器拓扑,必须用目标内核驱动定义、原理图和示波器确认引脚极性与上电斜率。
ISP 输入口固定 D-PHY、4 条数据 lane、映射 0x3210、VC0;路面相机经 IFE 输出 NV12,座舱相机走 RAW RDI 再交 BPS。configCSIPHY() 同样固定 lane_mask=0x1f、4 lane、lane_assign=0x3210、MIPI_SETTLE_CNT=33 和 data_rate=48000000——这些值没有来自 SensorInfo 的逐传感器能力协商,更换 lane 数、走线、时钟或 PHY 时,只增加一个传感器类是不够的。
座舱 BPS 初始化直接以 sensor->num() 索引 bps_cfg、bps_settings 和 bps_striping_output 三组固定二进制表。表声明仅有 4 个槽,前两个为占位,实际表与 ImageSensor 枚举值 2/3 绑定。新增枚举或热插拔传感器若不同步提供 BPS 表及索引验证,会在座舱路径出现无效配置或越界风险。
自动曝光的实际计算
CameraState::init() 从板级焦距、像素尺寸与输出缩放计算像素焦距,设置各路固定参考测光矩形,并初始化最近三帧的 EV。calculate_exposure_value() 在 NV12 Y 平面按 x=2, y=2(路面)或 y=4(座舱)抽样;从 255 向下累计直方图,取让高亮端累计至少达到样本数一半的亮度,再除以 256。它是抽样亮度的中位数近似,不是平均照度,也不是传感器原生统计直方图。
set_camera_exposure() 按 20 Hz 固定 dt=0.05 平滑目标灰度;根据三帧前的 EV 与当前测得灰度计算 desired_ev,约束到 min_ev..max_ev。随后只搜索当前模拟增益索引的 g-1..g+1,为每个候选求受限积分时间,并调用传感器的 getExposureScore() 评估 EV 误差、推荐增益代价和增益切换代价——这不是全增益表的全局最优搜索。转换增益在目标灰度跨越阈值时切换,并通过 dc_gain_weight 平滑增益因子。
曝光寄存器编码差异
两个传感器的寄存器写入方式不同,且有一处共同的静态边界:
| 实现 | 曝光寄存器编码 | 静态边界 |
|---|---|---|
| OS04C10 | 积分时间写 0x3501/02,同一模拟增益分别写 0x3508/09 与 0x350c/0d |
dc_gain_enabled 参数未参与此函数的寄存器生成 |
| OX03C10 | HCG/LCG、SPD 与 VS 时间分别写入;SPD 有下限/上限,VS 为积分时间约 1/40 并限定 1..34 行,模拟增益写 0x3508/09 |
dc_gain_enabled 同样未参与此函数的寄存器生成 |
两行的「静态边界」含义一致:软件的转换增益模型不能被理解为这里每帧必有对应寄存器切换;多曝光段的图像效果仍取决于初始化表和 ISP 配置。
输入风险与插件重构
源文档列出三类输入风险。第一,调试覆盖开关 CTRL_EXP_FROM_PARAMS 允许从 CameraDebugExpGain / CameraDebugExpTime 读取字符串并调用 std::stoi;在覆盖分支中未见范围检查,随后 sensor_analog_gains[new_exp_g] 与寄存器表直接按索引访问,负数、过大值和非数字分别可能造成越界或解析异常。第二,desired_ev 计算中直接除以测得 grey_frac,而亮度函数可返回零,标准浮点环境下暗帧会产生非有限中间值——该路径的最终值及 std::clamp 行为需测试确认。第三,测光 ROI 与 NV12 stride 的寻址差异:缓冲 Y 行步长是 128 字节对齐值,测光代码却按可见宽度换行,而固定的两种模组宽度都未对齐——后续算法描述是代码意图,不能据此认为它采样了光学 ROI 中对应的每个像素。
因此新「相机插件」至少要声明:探测/供电、I2C 与 MCLK、CSI 格式/步长、Bayer/ISP LUT、曝光实际生效延迟、SOF/EOF 时间域、镜头内外参和失效状态。源文档的定位很明确:插件可以提供传感器参数与采集能力,但时间戳真实性、帧有效性、模型输入契约和车辆执行许可应由受控平台层校验。对自制板,调试接口应与行车模式隔离并做显式限幅。
常见问题
为什么说曝光状态和寄存器值不是同一时刻的?
因为 set_camera_exposure() 用三帧前的 EV 计算 desired_ev,并按 20 Hz 固定 dt=0.05 平滑;最终参数通过 sensors_i2c() 排队写入下一帧配置。状态消息的曝光字段与随后提交的寄存器值之间存在帧延迟,不能不加延迟地视为同一时刻的物理测量。
传感器探测为什么不能只改 I2C 地址?
因为两种实现的 getSlaveAddress() 都把端口 0/1/2 映射为 0x6c/0x20/0x6c,而且探测还依赖固定上电/复位序列(1 ms、1 ms、34 ms)和 MCLK 24 MHz。新板的 I2C mux 与线序不能只靠改传感器 ID 解决,需用内核驱动定义、原理图和示波器核对。
为什么换一种 lane 数或走线不能只加一个传感器类?
因为 ISP 输入口与 configCSIPHY() 的参数是固定值(4 lane、lane_assign=0x3210、MIPI_SETTLE_CNT=33、data_rate=48000000),没有来自 SensorInfo 的逐传感器能力协商。更换 lane 数、时钟或 PHY 时,需要同步修改这些固定配置。
自动化曝光是「全增益表最优搜索」吗?
不是。它只搜索当前模拟增益索引的 g-1..g+1,为每个候选求受限积分时间,并由 getExposureScore() 评估 EV 误差、推荐增益代价和增益切换代价。因此它接近局部搜索,而非全局最优。
延伸阅读
- 硬件几何变换:相机内外参怎么进到模型输入 —— 承接像素焦距与安装姿态的链路。
- locationd 的四种健康位:20 Hz 输出为什么不能压缩成一个布尔值 —— 与本文 20 Hz 输出节奏及有效性分层的视角互补。
- 车载信号为什么会说谎:TTL、源时间与 500 ms 新鲜度阈值 —— 说明 SOF/EOF 时间域与新鲜度的通用边界。
- 同一个「转向灯」在三家车厂是三种实现:车辆状态归一化的坑 —— 硬件差异需要逐项归一化的同类问题。
参考资料
- 项目 02 ——
openpilot-research/CAMERA_SENSOR_EXPOSURE_ISP_DEEP_DIVE.md(取用了两套传感器契约、探测供电与 CSI/ISP 固定配置、曝光闭环与寄存器编码差异)。 - 项目 02 ——
openpilot-research/CAR_PROTOCOL_IMPLEMENTATIONS.md(仅用于确认车型配置与相机索引在整体链路中的位置)。
说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11
发表回复