RK ISP 硬件架构:你得先看懂这张图
做 3A 算法调优,说白了就是跟 ISP 硬件打交道。你要是连数据从哪进、从哪出、中间经过哪些模块都不清楚,那调参就跟闭着眼开车一样——能跑,但迟早翻车。
我个人习惯,拿到一块新芯片,第一件事不是看 datasheet 里的电气参数,而是先找到 ISP 的 block diagram。嗯,就是下面这张图。你先盯着看两分钟,我后面逐块拆给你听。
1. 数据从哪来?—— Sensor 输入与 MIPI 接口
图像数据从 Sensor 过来,走的是 MIPI CSI-2 或者 DVP 接口。RK 平台主流是 MIPI,支持 1-lane 到 4-lane,速率最高能到 2.5Gbps/lane 左右。数据进来之后,ISP 会先做格式解析,把 RAW 或者 YUV 数据打包成内部总线能识别的格式。
这里有个坑,我遇到过好几次:MIPI 的 lane 分配和 clock 极性如果配反了,出来的图像就是花的,或者干脆没图。调试的时候先用示波器看 clock 有没有,再看 data lane 的 eye diagram,别一上来就怀疑 ISP 配置。
dts 文件的 mipi_dphy 节点里,data-lanes 和 clock-noncontinuous 这两个字段最容易配错。
2. ISP 核心管线:从前端到后端的必经之路
数据进了 ISP 核心,会依次经过一系列硬件模块。我把它们分成两段:
2.1 前端 RAW 域处理
这部分操作的是 Sensor 直接出来的 RAW 数据,还没做颜色插值。主要模块有:
- BPC(坏点校正)——检测并替换 Sensor 上的死点或亮点。我习惯先跑一遍静态坏点表,再开动态检测,不然运动场景容易误判。
- BLS(黑电平校正)——减去 Sensor 的暗电流偏移。不同增益下黑电平会漂,记得做温度补偿。
- LSC(镜头阴影校正)——补偿镜头边缘亮度衰减。RK 的 LSC 用 9x9 或 17x17 网格,校准一次能管用,但换镜头模组必须重新标定。
- AWB Gain(白平衡增益)——这里只是乘 R/G/B 增益,真正的色温估计在后面的 3A 统计里做。
- Demosaic(去马赛克)——把 Bayer 格式插值成 RGB。RK 的 demosaic 有方向自适应算法,边缘伪色控制得还不错。
2.2 后端 RGB/YUV 域处理
数据变成 RGB 之后,进入后端管线:
- Gamma(伽马校正)——做亮度映射,标准 Rec.709 或 sRGB 曲线。RK 支持 12bit 查表,精度够用。
- WDR / HDR(宽动态)——多帧合成或者行交织 HDR。RK 的 HDR 支持 2 帧和 3 帧模式,合成权重可以调。
- CCM(色彩校正矩阵)——3x3 矩阵,把 Sensor 的 RGB 映射到标准色域。这个矩阵直接影响肤色,调的时候要对着色卡。
- RGB→YUV 转换——色彩空间转换,为后续编码和显示做准备。
- 2DNR / 3DNR(降噪)——空域降噪和时域降噪。3DNR 依赖运动检测,运动大的场景容易拖影,我一般把运动阈值调高一点。
3. 3A 统计引擎:闭环反馈的核心
ISP 处理完一帧数据后,3A 统计引擎会从图像中提取 AE(自动曝光)、AWB(自动白平衡)、AF(自动对焦)需要的统计信息。这些统计值通过 DMA 写到 DDR 里,然后 3A 算法库(比如 RK 的 lib3a)读取并计算新的控制参数,再写回 ISP 寄存器。
你看上面那张图里的红色虚线箭头,就是反馈回路。说白了,3A 算法就是靠这个闭环让图像自适应变化的场景。
4. 关键寄存器与接口
RK ISP 的寄存器通过 APB 总线访问,每个模块有一组独立的寄存器基地址。下面这张表列出了调试时最常用的几个寄存器组:
| 模块 | 基地址偏移 | 关键寄存器 | 作用 |
|---|---|---|---|
| MIPI RX | 0x0000 | CIF_MIPI_CTRL | MIPI 接口使能、lane 数、时钟极性 |
| BPC | 0x0100 | BPC_CTRL, BPC_TABLE | 坏点检测使能、静态坏点表写入 |
| BLS | 0x0200 | BLS_CTRL, BLS_OFFSET | 黑电平校正使能、R/Gr/Gb/B 偏移值 |
| LSC | 0x0300 | LSC_CTRL, LSC_GAIN_TBL | 镜头阴影校正使能、增益表基地址 |
| AWB Gain | 0x0400 | AWB_GAIN_R, AWB_GAIN_G, AWB_GAIN_B | 白平衡增益值(Q10 格式) |
| Demosaic | 0x0500 | DEMOSAIC_CTRL, DEMOSAIC_TH | 去马赛克算法选择、边缘阈值 |
| Gamma | 0x0600 | GAMMA_CTRL, GAMMA_LUT | 伽马校正使能、LUT 表基地址 |
| CCM | 0x0700 | CCM_MATRIX[0:8] | 3x3 色彩校正矩阵系数(Q12 格式) |
| 3A Stats | 0x1000 | AE_STAT, AWB_STAT, AF_STAT | AE/AWB/AF 统计结果 DMA 地址 |
接口方面,RK ISP 对外暴露的主要是 V4L2 和 Media Controller 框架。用户态通过 ioctl 设置参数,驱动层负责读写寄存器。3A 算法库通常跑在用户态,通过 /dev/videoX 节点获取统计数据和下发控制参数。
ioctl(VIDIOC_DBG_S_REGISTER) 可以直接读写 ISP 寄存器,适合快速验证某个模块是否生效。但注意别在生产代码里这么干,不安全。
5. 数据流走向总结
把整个流程串起来,就是一句话:
- Sensor 输出 RAW 数据 → MIPI 接口接收
- ISP 前端:BPC → BLS → LSC → AWB Gain → Demosaic
- ISP 后端:Gamma → WDR/HDR → CCM → RGB→YUV → 2DNR/3DNR
- 3A 统计引擎提取 AE/AWB/AF 统计 → DMA 到 DDR
- 3A 算法库计算新参数 → 写回 ISP 寄存器 → 下一帧生效
- 最终 YUV 数据输出到 DDR、显示或编码器
嗯,这个流程你记熟了,后面调 AE、AWB、AF 的时候,你就能知道每个参数到底影响的是哪个环节。我曾经在调 AWB 的时候,死活调不准,最后发现是 LSC 的增益表没校准,导致边缘色偏影响了 AWB 统计。你看,硬件链路不熟,调参就是瞎忙活。