3. MIPI CSI-2协议层详解:长包与短包格式、数据类型与虚拟通道

各位同学,今天我们来啃一块硬骨头——MIPI CSI-2的协议层。说实话,我刚接触MIPI时,被那一堆包格式、校验机制搞得头大。但后来我发现,只要抓住几个核心概念,这东西其实挺有规律的。

CSI-2协议层,说白了就是定义摄像头怎么把数据“打包”发给处理器。它有两种包:长包和短包。我习惯把长包想象成“运货的卡车”,短包则是“发信号的对讲机”。

3.1 长包与短包格式

短包(Short Packet)只有4个字节:数据标识符(DI)+ 2字节数据 + 1字节ECC。它不携带图像数据,只传递控制信息。比如告诉接收端“下一帧开始了”、“这一行结束了”。

长包(Long Packet)就复杂多了。它由三部分组成:

  • 包头(Packet Header):4字节,包含DI、字计数(WC)、ECC
  • 数据负载(Data Payload):长度由WC指定,最大65535字节
  • 包尾(Packet Footer):2字节CRC校验

关键点:长包的数据负载必须是字节对齐的。我在项目中遇到过,如果RAW10数据没处理好对齐,接收端会直接丢包。

3.2 数据类型(DT)与虚拟通道(VC)

数据标识符(DI)这个字节,高2位是虚拟通道(VC),低6位是数据类型(DT)。

位域 名称 说明
[7:6] VC 虚拟通道,0-3,用于区分不同摄像头
[5:0] DT 数据类型,0x00-0x3F

VC的作用很实用。比如我做双目视觉时,两个摄像头共用同一组差分线,靠VC=0和VC=1来区分左右眼数据。嗯,这里要注意:接收端必须根据VC来解复用数据流。

DT值决定了数据格式。常用的有:

  • 0x00:帧起始码(Frame Start)
  • 0x01:帧结束码(Frame End)
  • 0x02:行起始码(Line Start)
  • 0x03:行结束码(Line End)
  • 0x2A-0x2D:RAW8/10/12/14/16
  • 0x1E:YUV420 8位

避坑指南:我曾经在调试时发现图像错位,查了半天,原来是DT配置成了RAW12,但传感器实际输出的是RAW10。接收端按12位解析,数据全乱了。

3.3 帧格式:Frame Start/End、Line Start/End

CSI-2的帧结构其实很简单。一帧图像由以下序列组成:

FS (Frame Start) 短包
  LS (Line Start) 短包
  行数据 (长包)
  LE (Line End) 短包
  ... (重复LS+行数据+LE)
FE (Frame End) 短包

你想想看,为什么需要Line Start和Line End?我个人的理解是:这相当于给每行数据加了“边界标记”。如果某行数据出错,接收端可以快速定位到下一行的起始位置,不至于整帧都废掉。

这里有个细节:FS和FE是必须的,但LS和LE是可选的。有些传感器为了省带宽,会省略行边界标记。但我建议你尽量保留,调试时能省不少事。

3.4 CRC与ECC校验机制

CSI-2用了两种校验,各有分工:

  • ECC(纠错码):保护短包和长包包头。它能纠正1位错误,检测2位错误。
  • CRC(循环冗余校验):保护长包的数据负载。只能检错,不能纠错。

为什么会这样设计?ECC计算简单,适合实时性要求高的包头。CRC计算量大,但检错能力强,适合数据量大的负载。

注意:ECC只能纠正1位错误。如果传输环境噪声大,2位以上的错误会导致丢包。我在做车载摄像头时,遇到过电磁干扰导致频繁丢帧,最后不得不降低CSI-2时钟频率来保证稳定性。

3.5 Raw数据格式:RAW8/10/12/14/16

RAW格式是传感器最原始的像素数据。不同位深对应不同的数据排列方式:

格式 每像素位数 存储方式
RAW8 8 1字节/像素,最简单
RAW10 10 4像素打包成5字节
RAW12 12 2像素打包成3字节
RAW14 14 4像素打包成7字节
RAW16 16 2字节/像素,高位对齐

RAW10的打包方式我得多说两句。4个10位像素(共40位)被塞进5个字节里。具体排列是:

Byte 0: Pixel0[9:2]
Byte 1: Pixel1[9:2]
Byte 2: Pixel2[9:2]
Byte 3: Pixel3[9:2]
Byte 4: Pixel3[1:0] | Pixel2[1:0] | Pixel1[1:0] | Pixel0[1:0]

说白了,每个像素的高8位占一个完整字节,低2位被拼凑到第5个字节里。这种打包方式在FPGA里实现起来有点绕,我建议你画个状态机来处理字节对齐。

实战经验:RAW12的2像素打包成3字节,其实和RAW10的思路类似。但要注意,有些传感器会输出“未对齐”的RAW12,即每个像素占2字节(高12位有效,低4位填充0)。这种格式虽然浪费带宽,但处理起来简单。我一般建议在FPGA内部统一转换成16位对齐,后续处理会方便很多。

3.6 知识体系总览

下面这张图总结了CSI-2协议层的核心逻辑。你可以把它当作调试时的“地图”。

MIPI CSI-2 协议层核心结构 短包 (Short Packet) 4字节固定长度 DI (1B) + 数据 (2B) + ECC (1B) 用途:FS, FE, LS, LE ECC可纠正1位错误 长包 (Long Packet) 可变长度 包头 (4B) + 数据 + 包尾 (2B) 包头含DI, WC, ECC 包尾为CRC16校验 数据标识符 DI (1 Byte) VC[1:0] (2位) + DT[5:0] (6位) 帧结构示例 FS → LS → 行数据(长包) → LE → ... → LS → 行数据 → LE → FE FS/FE必须存在,LS/LE可选

这张图把短包、长包、DI结构、帧结构串在了一起。你调试时如果遇到问题,先定位是哪个环节出了错——是包头ECC校验失败?还是CRC对不上?还是帧结构不完整?

好了,这一章的内容就到这里。CSI-2协议层虽然细节多,但核心就是“包”和“校验”这两个概念。下一章我们会深入物理层,看看这些包是怎么在差分线上传输的。

个人建议:如果你刚开始做MIPI调试,先用逻辑分析仪抓一组完整的帧数据,对照着协议手册逐字节分析。我当年就是这么干的,虽然慢,但理解会非常深刻。

可可精品资料库