4、MIPI CSI-2 协议层:长包与短包格式、数据类型与虚拟通道、帧同步与行同步机制
好,我们进入 MIPI CSI-2 协议层。说实话,这部分是驱动开发中最绕、也最容易出 bug 的地方。很多工程师调不通 sensor,最后发现不是硬件问题,而是协议层的包格式没搞对。
MIPI CSI-2 的协议层,说白了就是定义数据怎么打包、怎么传输、怎么解析。它把数据分成两种包:长包和短包。这两种包配合起来,才能完成一帧图像的完整传输。
4.1 长包与短包:协议层的两种基本单元
先看短包。短包只有 32 位数据,结构非常简单:
短包格式(32位):
+--------+--------+--------+--------+
| Data ID | Word Count / ECC | ECC |
+--------+--------+--------+--------+
- Data ID(8位):虚拟通道 + 数据类型
- Word Count / 数据(16位):短包的数据字段
- ECC(8位):纠错码
短包不传图像数据,它只传控制信息。比如帧开始、帧结束、行开始、行结束。我刚开始做 sensor 驱动时,以为短包不重要,结果图像一直花屏。查了两天,发现是帧同步的短包时序不对。
长包才是真正传图像数据的。它的结构稍微复杂一点:
长包格式:
+--------+--------+--------+--------+------------------+--------+
| Data ID | Word Count | ECC | 图像数据(可变长) | CRC |
+--------+--------+--------+--------+------------------+--------+
- Data ID(8位):虚拟通道 + 数据类型
- Word Count(16位):数据负载的字节数
- ECC(8位):包头纠错码
- 数据负载:实际图像数据
- CRC(16位):数据校验码
长包的核心是 Word Count 字段。它告诉接收端这包数据有多长。接收端根据这个值来切分数据流。嗯,这里要注意:Word Count 的单位是字节,不是像素。
关键点:长包和短包的区别不在于数据量,而在于用途。短包是控制信令,长包是数据传输。两者通过 Data ID 中的数据类型字段区分。
4.2 数据类型与虚拟通道:如何区分不同的数据流
Data ID 是 8 位字段,它包含两部分:
- 高 2 位:虚拟通道标识(Virtual Channel, VC)
- 低 6 位:数据类型标识(Data Type, DT)
虚拟通道有什么用?你想想看,一个 MIPI 接口可以同时传多路数据。比如双摄像头模组,或者摄像头同时输出 RAW 和 YUV 两路数据。虚拟通道就是用来区分这些数据流的。
数据类型定义了负载的格式。我整理了一份常用的数据类型表:
| 数据类型 | 值(十六进制) | 说明 |
|---|---|---|
| RGB888 | 0x1E | 24位 RGB 格式 |
| RAW8 | 0x2A | 8位 RAW 数据 |
| RAW10 | 0x2B | 10位 RAW 数据 |
| RAW12 | 0x2C | 12位 RAW 数据 |
| YUV420 8bit | 0x1E | YUV 420 格式 |
| 帧开始(FS) | 0x00 | 短包,帧同步开始 |
| 帧结束(FE) | 0x01 | 短包,帧同步结束 |
| 行开始(LS) | 0x02 | 短包,行同步开始 |
| 行结束(LE) | 0x03 | 短包,行同步结束 |
个人经验:配置 sensor 时,一定要确认 sensor 输出的数据类型和驱动中配置的一致。我曾经遇到一个 case,sensor 输出 RAW10,但驱动配成了 RAW8,结果图像全是条纹。查了半天才发现是数据类型不匹配。
4.3 帧同步与行同步机制:图像传输的骨架
帧同步和行同步,是 MIPI CSI-2 协议中最核心的时序机制。没有它们,接收端根本不知道哪里是图像的开始和结束。
帧同步的流程是这样的:
- 发送端先发一个 帧开始(FS) 短包
- 然后逐行发送图像数据(每行是一个长包)
- 所有行发送完毕后,发一个 帧结束(FE) 短包
行同步的流程类似:
- 每行开始前,发一个 行开始(LS) 短包
- 然后发送该行的图像数据(长包)
- 行数据发完后,发一个 行结束(LE) 短包
我画了一张图,帮你理解这个时序关系:
为什么需要行同步?因为接收端需要知道每行数据的边界。如果没有行同步,接收端无法判断数据流中哪里是一行的结束、下一行的开始。特别是在传输 RAW 数据时,每行的像素数可能不是固定的。
4.4 协议层的实际配置要点
在实际驱动开发中,协议层的配置主要集中在 sensor 的寄存器设置上。我总结几个关键点:
- 数据类型配置:sensor 的输出格式必须和 CSI-2 接收端匹配。比如 sensor 输出 RAW10,接收端也要配成 RAW10。
- 虚拟通道配置:如果使用多路数据,每路数据要分配不同的虚拟通道 ID。
- 帧同步使能:确认 sensor 是否开启了帧同步和行同步的短包输出。有些 sensor 默认不开启。
- Word Count 验证:接收端收到长包后,会检查 Word Count 是否和实际数据长度一致。不一致会报错。
避坑指南:我曾经遇到一个 case,sensor 输出的帧率一直不对。查了很久,发现是 sensor 的帧同步配置中,帧开始和帧结束的短包之间插入了额外的空白包。接收端把这些空白包当成了有效数据,导致帧计数错误。解决方案是在 sensor 的寄存器中关闭空白包输出。
4.5 协议层与物理层的配合
协议层和物理层是紧密配合的。物理层负责把协议层的包转换成差分信号,通过 D-PHY 或 C-PHY 传输。协议层不关心物理层用什么接口,它只定义包的格式和时序。
但有一点要注意:协议层的包长度不能超过物理层的传输能力。比如 D-PHY 的每个 lane 有最大速率限制,如果长包的数据量太大,会导致传输时间过长,影响帧率。