嵌入式ISP硬件架构:从模块划分到数据流设计

做ISP调试这些年,我最大的感触是:不懂硬件架构,你连图像为什么偏色都查不明白。这一章咱们就聊聊嵌入式ISP的硬件骨架——模块怎么切、ARM和FPGA怎么配合、数据怎么在芯片里跑起来。

ISP硬件模块划分

一个完整的ISP流水线,硬件上可以拆成几个核心模块。我习惯把它们分成三类:前端处理、中间处理、后端输出。

模块分类 典型模块 硬件实现 数据特点
前端处理 DPC、BLC、LSC、AWB FPGA/专用ISP RAW域,逐像素流水
中间处理 Demosaic、CCM、Gamma、WDR FPGA/GPU RGB域,块处理为主
后端输出 缩放、色彩空间转换、编码 FPGA/CPU YUV域,帧级处理

前端模块处理的是传感器直接出来的RAW数据。每个像素只有一种颜色分量,数据量最大,但算法相对固定。我做过一个项目,前端用了纯FPGA流水线,DPC和BLC在一个时钟周期内就能完成,延迟只有几行像素。

中间处理模块最复杂。Demosaic要把Bayer阵列恢复成RGB,CCM做色彩校正,Gamma做亮度映射。这些模块往往需要行缓存或小块缓存,FPGA的BRAM正好派上用场。

后端输出模块相对灵活。缩放可以用查表法,色彩空间转换用矩阵乘法,编码可以交给CPU软处理。嗯,这里要注意:后端模块的数据量已经降下来了,用ARM处理完全够用。

关键点:模块划分的核心原则是——数据率高的往前放,算法固定的用硬件,需要灵活配置的留给软件。我在项目中吃过亏,把AWB的统计模块放在后端,结果因为数据压缩后精度不够,白平衡怎么调都偏色。

ARM+FPGA异构计算平台

为什么选ARM+FPGA?说白了,就是既要灵活性又要性能。ARM擅长控制流和复杂算法,FPGA擅长数据流和并行计算。

我常用的架构是这样的:

  • ARM侧:跑Linux系统,负责ISP参数配置、3A算法(AWB/AE/AF)、用户交互
  • FPGA侧:实现像素级流水线,处理RAW到YUV的转换,做实时统计
  • 共享内存:ARM写配置寄存器,FPGA写统计结果,通过DMA交互

你想想看,如果全部用ARM做ISP,4K@30fps的数据量是每秒约300MB,ARM根本扛不住。全部用FPGA呢?算法迭代一次要重新综合,开发周期太长。ARM+FPGA正好互补。

个人经验:我建议把3A算法放在ARM上跑。原因很简单——3A算法经常要调参、要加新策略,FPGA改起来太痛苦。我在一个项目中把AWB统计放在FPGA,算法逻辑放在ARM,调试效率高了很多。

ARM和FPGA之间的通信,我一般用AXI总线。ARM通过AXI-Lite写配置寄存器,FPGA通过AXI-Full搬数据。带宽够用,延迟也低。

DMA与数据流设计

数据流设计是ISP硬件架构的核心。数据怎么从传感器进FPGA,怎么在模块间流转,怎么送到ARM,每一步都影响最终效果。

我画了一张典型的数据流图,你看看就明白了:

ISP数据流与DMA架构 CMOS传感器 MIPI接收 ISP流水线 DPC→BLC→Demosaic →CCM→Gamma→WDR DMA引擎 DDR内存 ARM处理器 数据流说明: 1. 传感器通过MIPI接口输出RAW数据,速率可达2.5Gbps/lane 2. MIPI接收模块将串行数据转为并行,送入ISP流水线 3. ISP流水线逐像素处理,输出YUV数据 4. DMA引擎将YUV数据搬入DDR,ARM从DDR读取做后处理 5. ARM通过AXI-Lite配置ISP参数,FPGA通过中断通知ARM

DMA设计有几个坑,我一个个说:

  • 带宽匹配:DMA的时钟频率要和ISP流水线匹配。我曾经把DMA时钟设低了,结果数据堆积,丢帧严重
  • 地址对齐:DMA传输的起始地址要按128字节对齐,否则性能下降30%以上
  • 中断处理:每帧一个中断就够了,不要每行都中断,ARM会被淹死

避坑指南:我曾经在一个项目中用了分散-聚集DMA,想着能提高效率。结果调试了整整两周,发现是描述符链表指针没对齐,导致DMA死循环。后来我学乖了——能用简单DMA就别用复杂DMA,稳定第一。

MIPI接口协议

MIPI是传感器和ISP之间的桥梁。说白了,就是把传感器的并行数据串行化,用差分信号高速传输。

MIPI CSI-2的物理层分三层:

  1. PHY层:差分信号,D-PHY最高2.5Gbps/lane,C-PHY更高
  2. Lane管理层:把数据分发到多个lane,接收端重新合并
  3. 协议层:定义帧头、行头、数据类型(RAW8/RAW10/YUV等)

我常用的配置是4-lane D-PHY,速率1.5Gbps/lane,总带宽6Gbps。对于4K@30fps的RAW10数据,带宽需求约2.4Gbps,完全够用。

MIPI调试中最容易出问题的是时钟。MIPI的时钟是DDR模式,上升沿和下降沿都采样数据。如果时钟抖动太大,数据就会出错。我建议在PCB设计时,MIPI走线要等长,差分阻抗控制在100欧姆。

调试技巧:MIPI信号用示波器看眼图。眼图张开越大,信号质量越好。如果眼图闭合,先查时钟抖动,再查走线长度。我遇到过一个问题——MIPI线长了5mm,结果4K分辨率下图像有横纹,缩短走线后就好了。

MIPI协议层有个容易忽略的点:数据类型。传感器输出的RAW10数据,MIPI协议里用0x2B标识。如果ISP端配置错了数据类型,图像就会花掉。我建议在初始化时,先读传感器的寄存器确认输出格式,再配置MIPI接收端。