4、CSI-2 协议层:长包与短包格式、数据类型定义、虚拟通道机制
好,咱们今天聊聊 CSI-2 的协议层。说实话,很多工程师做 MIPI 调试,硬件上拉个波形没问题,但一遇到图像花屏、数据错位,就抓瞎了。为什么?因为没搞懂协议层在干什么。
协议层,说白了就是摄像头和处理器之间约定好的“说话方式”。你发一串 0 和 1,对方得知道哪是头、哪是尾、中间是什么数据。CSI-2 协议层就干这个事。
4.1 长包与短包:两种基本“信封”
CSI-2 的数据传输,分两种包:长包(Long Packet)和短包(Short Packet)。我习惯把它们比作寄快递:
- 短包:就像一张明信片。内容少,就写个“帧开始”、“帧结束”之类的控制信息。32 位数据,一次搞定。
- 长包:就像一个大箱子。里面装的是真正的图像数据(像素)。箱子外面贴着快递单(包头),里面是货物(有效数据),最后还有个签名(校验)。
咱们先看短包格式。它很简单:
短包格式(32位):
[Data ID (8位)] [Word Count (16位)] [ECC (8位)]
等等,你可能要问:短包只有 32 位,那 Word Count 字段干嘛用的?嗯,这里有个细节——短包的 Word Count 字段其实被用来存放“短包数据内容”了,比如帧号、行号这些。ECC 是纠错码,保证这 32 位别传错。
长包就复杂一些:
长包格式:
[包头: Data ID (8位) + Word Count (16位) + ECC (8位)]
[有效数据: Word Count 字节]
[包尾: 16位 CRC 校验]
我在项目中遇到过一个问题:某款 sensor 输出的长包,Word Count 和实际数据长度对不上。结果图像下半部分全是乱的。后来发现是 sensor 的寄存器配置错了,把行长度设成了奇数。记住,长包的有效数据必须是 32 位对齐的,不够的要补 0。
4.2 数据类型(Data Type):给数据贴个标签
数据类型,就是告诉接收方:“我这包数据是什么格式”。它放在每个包的 Data ID 字段里,占高 6 位(低 2 位是虚拟通道号)。
常见的 Data Type 我列个表,你调试时肯定用得上:
| Data Type (十六进制) | 含义 | 说明 |
|---|---|---|
| 0x00-0x07 | 保留 | 别用,用了可能出奇怪问题 |
| 0x08-0x0F | 短包(帧/行同步) | 0x00: 帧开始, 0x01: 帧结束, 0x02: 行开始, 0x03: 行结束 |
| 0x10-0x17 | 通用短包 | 留给厂商自定义,我一般不用 |
| 0x18-0x1F | 通用长包 | 同上,非标数据用 |
| 0x2A | RAW8 | 8位原始Bayer数据,最常用 |
| 0x2B | RAW10 | 10位原始数据,4个像素占5字节 |
| 0x2C | RAW12 | 12位原始数据,2个像素占3字节 |
| 0x2D | RAW14 | 14位,工业相机用得多 |
| 0x1E | RGB888 | 24位RGB,调试时方便看 |
| 0x1C | YUV420 8位 | 视频压缩常用 |
我个人习惯,调试初期先把 sensor 配成 RAW8 或 RGB565。为什么?因为数据量小,逻辑分析仪抓包容易看。等通路调通了,再换成 RAW10 或 RAW12 提高画质。
4.3 虚拟通道(Virtual Channel):一根线上跑多路数据
虚拟通道,是 CSI-2 里一个非常巧妙的设计。你想想看,现在的手机摄像头模组,经常是主摄、广角、景深好几个 sensor 同时工作。难道每个 sensor 都拉一组 MIPI 线到处理器?那板子得乱成什么样。
虚拟通道就是解决这个问题的。它允许最多 4 个不同的数据流,共用同一组 MIPI 物理通道(D-PHY 的 1 对时钟 + 1~4 对数据线)。每个数据流通过 Data ID 的低 2 位来区分,也就是 VC0 ~ VC3。
看个实际例子。假设你有个双摄模组:
- 主摄(RAW10, 1920x1080)→ VC0
- 景深(RAW8, 640x480)→ VC1
这两个 sensor 的数据会交替出现在同一条 MIPI 数据线上。接收端(处理器)根据 Data ID 里的 VC 号,把数据分别送到不同的处理模块。就像一条高速公路上,不同颜色的车走不同的车道。
我画个图帮你理解:
看到没?VC0 和 VC1 的包是交错传输的。接收端拿到每个包,先看低 2 位是 00 还是 01,然后分别处理。这样一根 MIPI 线就相当于变成了 4 根虚拟的线。
4.4 避坑指南:协议层常见问题
最后,我分享几个实际项目中踩过的坑:
- 短包丢失导致帧同步失败:我曾经遇到一个案子,图像偶尔会卡住不动。抓波形发现,sensor 输出的帧开始短包(0x00)偶尔会丢失。原因是 sensor 的电源纹波太大,导致内部逻辑偶尔复位。加了个电容就好了。
- Data Type 不匹配:这个前面提过。调试时一定先用逻辑分析仪抓一下包,确认 Data Type 字段的值。别信 sensor 的 datasheet,有时候它写的是错的。
- 虚拟通道冲突:如果你用多路 sensor,记得每个 sensor 的 VC 号要唯一。我见过两个 sensor 都配成 VC0 的,结果数据混在一起,图像像万花筒。
- Word Count 越界:长包的 Word Count 字段是 16 位的,最大 65535 字节。如果你的行数据超过这个值,必须拆成多个长包。有些 sensor 不会自动拆分,需要你手动配寄存器。
嗯,协议层的东西就这些。说白了,就是搞清楚“谁在什么时候发了什么数据”。你只要把包格式、数据类型、虚拟通道这三个概念吃透了,CSI-2 的协议层就没什么能难住你的了。