2. MIPI CSI-2协议详解:物理层与协议层
MIPI CSI-2,说白了就是摄像头和处理器之间的「普通话」。没有它,Sensor拍得再好,数据也传不过去。我刚开始调ISP那会儿,遇到图像花屏,第一反应就是查Sensor配置,折腾半天才发现是MIPI的时序没对准。嗯,从那以后,我养成了一个习惯——先搞定MIPI,再谈图像质量。
这一章,我们重点拆解CSI-2的物理层和协议层。你不需要背协议文档,但得理解它的设计思路。这样以后遇到信号不稳定、数据错位、带宽不够的问题,你才知道从哪里下手。
2.1 物理层:D-PHY vs C-PHY
物理层负责把0和1变成电信号,在线上跑。MIPI联盟主推两种物理层:D-PHY和C-PHY。目前绝大多数Sensor用的是D-PHY,但C-PHY在高端手机上越来越常见。
| 特性 | D-PHY | C-PHY |
|---|---|---|
| 信号线 | 差分对(Dp/Dn),每对2根线 | 三线制(A/B/C),每通道3根线 |
| 时钟 | 独立时钟线(Clk+/Clk-) | 无独立时钟,数据内嵌时钟 |
| 每通道带宽 | 最高约2.5 Gbps(D-PHY v2.0) | 最高约5.7 Gbps(C-PHY v2.0) |
| 抗干扰 | 差分信号,抗共模噪声好 | 三线差分,抗干扰更强 |
| 典型应用 | 主流手机、车载、安防 | 高端手机、高帧率/高分辨率 |
我的经验: 选D-PHY还是C-PHY,主要看带宽需求。如果Sensor输出4K@60fps以上,或者RAW14位深,D-PHY的4通道可能不够用,这时候C-PHY的3通道就能省下不少PCB空间。但C-PHY的协议解析更复杂,驱动调试周期会长一些。
2.1.1 D-PHY的Lane结构
D-PHY的每个通道(Lane)由一对差分线组成。一对时钟线(Clk+/-)加一对或多对数据线(Data+/-)。时钟线是单向的,从主机发往设备;数据线是双向的,但CSI-2场景下通常只用于从Sensor到处理器的单向传输。
D-PHY有两种工作模式:
- 高速模式(HS): 传输图像数据,差分摆幅约200mV,速率高,功耗也高。
- 低功耗模式(LP): 传输控制信号(如进入/退出HS模式),单端信号,摆幅约1.2V,速率低,功耗极低。
为什么要有LP模式?你想想看,Sensor不是每时每刻都在传数据。帧与帧之间的消隐期,如果还跑在HS模式,功耗就浪费了。LP模式就是用来省电的。
避坑指南: 我曾经遇到一个项目,Sensor在低帧率下工作正常,一提高帧率就丢帧。查了半天,发现是D-PHY的LP→HS切换时间没配够。协议规定这个切换时间至少是T_LPX + T_HS-PREPARE + T_HS-ZERO,但不同Sensor的时序参数有差异。建议你在驱动初始化时,先读Sensor的datasheet,把这几项时序配到最保守值,稳定后再优化。
2.1.2 C-PHY的三线差分
C-PHY没有独立的时钟线。它用三根线(A/B/C)的电压状态组合来编码数据和时钟。每根线有三种电平:高、低、中间。三根线组合起来,每个符号可以表示3种状态(实际是3! = 6种,但只用其中3种做差分编码)。
这样做的好处是:
- 省掉了时钟线,同样数量的物理引脚可以跑更多数据通道。
- 三线差分对共模噪声的抑制更好,适合长距离传输。
但代价是协议解析更复杂。C-PHY的接收端需要做符号同步和时钟恢复,对硬件要求更高。
2.2 协议层:长包与短包
物理层搞定信号传输,协议层负责把数据组织成有意义的「包」。CSI-2协议层定义了两种包:短包和长包。
2.2.1 短包(Short Packet)
短包只有4个字节:1字节数据标识符(DI)+ 2字节数据 + 1字节ECC。它不携带图像数据,只传递控制信息。常见的短包类型:
- 帧开始(Frame Start): 通知接收端,新的一帧要来了。
- 帧结束(Frame End): 通知接收端,当前帧传输完毕。
- 行开始(Line Start): 通知接收端,新的一行要来了。
- 行结束(Line End): 通知接收端,当前行传输完毕。
短包里的2字节数据,对于帧开始/结束包来说,存放的是帧号;对于行开始/结束包来说,存放的是行号。接收端可以根据这些信息判断数据是否完整。
关键点: ECC(纠错码)可以纠正1位错误,检测2位错误。短包只有4字节,ECC占1字节,冗余度很高。为什么?因为控制信息一旦出错,可能导致整帧数据解析错误。协议设计者在这里下了重注。
2.2.2 长包(Long Packet)
长包是图像数据的载体。它的结构是:
- 包头(4字节): 数据标识符(DI)+ 字计数(WC)+ ECC。字计数告诉接收端后面有多少字节的数据载荷。
- 数据载荷(可变长度): 真正的图像数据,按字节排列。
- 包尾(2字节): 校验和(Checksum),用于验证数据完整性。
数据标识符(DI)里包含了两个关键信息:虚拟通道号(VC)和数据类型(DT)。我们接下来细说。
2.3 虚拟通道(Virtual Channel)
虚拟通道是CSI-2协议里一个非常巧妙的设计。它允许在同一个物理链路上传输多路独立的图像数据流。比如,一个双摄模组,主摄和副摄可以共用同一组MIPI线,通过不同的虚拟通道号区分。
虚拟通道号占用DI的高2位(VC[1:0]),所以最多支持4个虚拟通道(0~3)。接收端根据VC号把数据分发到不同的处理单元。
| 虚拟通道 | 典型用途 |
|---|---|
| VC0 | 主摄像头图像数据 |
| VC1 | 副摄像头图像数据 |
| VC2 | 深度传感器数据 |
| VC3 | 元数据(如陀螺仪、时间戳) |
我的建议: 如果你在做多摄方案,尽量把不同Sensor的VC号固定下来,比如主摄用VC0,广角用VC1。这样驱动代码里写死VC号,调试时一眼就能看出数据来自哪个Sensor。我曾经见过一个项目,两个Sensor的VC号在驱动里配反了,图像花了好几天才调回来。
2.4 数据格式:RAW8/10/12/14
Sensor输出的原始数据,最常见的就是RAW格式。RAW格式的位深决定了每个像素用多少位来表示。常见的位深有8、10、12、14。
数据格式在长包的DI中通过数据类型(DT)字段指定。接收端根据DT字段决定如何解析数据载荷。
| 数据类型 | DT值(Hex) | 每像素位数 | 典型应用 |
|---|---|---|---|
| RAW8 | 0x2A | 8 | 低端Sensor、预览模式 |
| RAW10 | 0x2B | 10 | 主流手机Sensor |
| RAW12 | 0x2C | 12 | 车载、安防、工业相机 |
| RAW14 | 0x2D | 14 | 高端摄影、医疗影像 |
2.4.1 数据打包方式
不同位深的RAW数据在MIPI链路上传输时,打包方式不一样。这里有个容易踩坑的地方。
- RAW8: 每个像素占1字节,直接按字节排列。简单粗暴。
- RAW10: 每个像素占10位。4个像素打包成5字节(4×10=40位=5字节)。接收端需要按位拆包。
- RAW12: 每个像素占12位。2个像素打包成3字节(2×12=24位=3字节)。
- RAW14: 每个像素占14位。4个像素打包成7字节(4×14=56位=7字节)。
// RAW10 打包示例:4个像素(P0~P3)打包成5字节
// 字节0: P0[9:2] (高8位)
// 字节1: P1[9:2] (高8位)
// 字节2: P2[9:2] (高8位)
// 字节3: P3[9:2] (高8位)
// 字节4: P3[1:0] P2[1:0] P1[1:0] P0[1:0] (低2位拼接)
避坑指南: 我曾经在调试RAW10的Sensor时,图像一直有条纹。后来发现是接收端把字节4的位顺序搞反了。协议规定低2位的拼接顺序是P3→P2→P1→P0,但有些Sensor的datasheet可能画反。建议你拿到新Sensor后,先拍一张纯色图,用逻辑分析仪抓一下MIPI数据,确认打包顺序和协议一致。
2.4.2 位深与带宽的关系
位深越大,图像质量越好,但带宽需求也越大。举个例子:
- 一个200万像素的Sensor,输出RAW10,帧率30fps:带宽 = 1920×1080×10×30 ≈ 622 Mbps。
- 同样分辨率,换成RAW14:带宽 = 1920×1080×14×30 ≈ 871 Mbps。
如果MIPI只有2个D-PHY通道,每通道最高2.5 Gbps,总带宽5 Gbps,看起来绰绰有余。但别忘了,MIPI传输还有消隐期、包开销、ECC等额外消耗。实际可用带宽大约是理论值的80%~90%。
经验公式: 我一般按「像素时钟 × 位深 × 1.15」来估算实际需要的MIPI带宽。多出来的15%是给消隐期和协议开销的。如果算出来超过物理层带宽的80%,我就会考虑增加通道数或者换C-PHY。
2.5 本章小结
MIPI CSI-2协议,从物理层的D-PHY/C-PHY,到协议层的短包/长包,再到虚拟通道和数据格式,每一层都有它的设计意图。物理层解决信号传输,协议层解决数据组织,虚拟通道解决多路复用,数据格式解决像素表达。
你不需要记住所有细节,但得理解这些概念之间的关系。下次调驱动时,遇到图像花屏,先查物理层(信号完整性);遇到数据错位,查协议层(包结构);遇到多路冲突,查虚拟通道;遇到颜色不对,查数据格式。按这个思路排查,效率会高很多。