3. 协议层架构:CSI-2协议分层模型、像素字节包装格式、长包与短包结构、ECC与校验机制

好,咱们今天来聊聊CSI-2协议的核心——协议层架构。这部分内容,说白了就是搞清楚摄像头的数据是怎么从传感器一路跑到你的处理器里的。我当年第一次调MIPI接口时,被这些包结构折腾得够呛,后来才明白,理解了这一层,驱动开发就成功了一半。

3.1 CSI-2协议分层模型

CSI-2协议不是一个大铁块,它是分层的。就像网络协议有七层一样,CSI-2也有自己的层次结构。我个人习惯把它分成三层来看:

  • 应用层(Application Layer):最上层,负责像素数据的组织和格式。说白了,就是你的摄像头拍出来的RAW10、RAW12、YUV422这些数据,怎么排列、怎么打包,都是这层说了算。
  • 协议层(Protocol Layer):中间层,负责数据包的封装、解析、校验。长包、短包、ECC校验,全在这层。这是咱们驱动工程师打交道最多的地方。
  • 物理层(Physical Layer):最底层,负责电信号的传输。D-PHY、C-PHY这些,就是干这个活的。

你想想看,这三层各司其职。应用层只管“我要传什么数据”,协议层管“怎么把数据打包好”,物理层管“怎么把包发出去”。分层的好处很明显——哪层出问题,就查哪层。我在项目中遇到过好几次,图像花屏了,第一反应是物理层信号有问题,结果查了半天,其实是应用层的像素格式配置错了。

重点提醒:驱动开发时,这三层的配置是联动的。你应用层配了RAW10,协议层就得按RAW10的规则打包,物理层也得匹配对应的数据速率。少配一个,图像就出不来。

3.2 像素字节包装格式

像素数据怎么装进字节里?这个问题看似简单,但坑不少。CSI-2支持多种像素深度,比如8位、10位、12位、14位、16位。每种深度,包装方式都不一样。

我拿最常见的RAW10来举例。RAW10每个像素占10位,但字节是8位的。怎么塞?CSI-2的做法是:每4个像素打包成5个字节。具体来说:

  • 像素0的10位数据,占字节0和字节1的高2位
  • 像素1的10位数据,占字节1的低6位和字节2的高4位
  • 像素2的10位数据,占字节2的低4位和字节3的高6位
  • 像素3的10位数据,占字节3的低2位和字节4的全部8位

嗯,这里要注意,不同厂商的传感器,打包顺序可能不一样。有的先传高位,有的先传低位。我踩过这个坑——当时调试一款索尼的传感器,按标准方式解析,图像全是乱的。后来发现它用的是“高位对齐”的打包方式。

我的经验:拿到一款新传感器,先看它的数据手册里有没有“Pixel Order”或者“Data Format”的说明。如果没有,就抓一帧原始数据,自己画个表格,一个一个像素对。虽然麻烦,但最可靠。

下面这个表格,列出了常见像素格式的打包方式:

像素格式 每像素位数 打包方式 每N个像素占字节数
RAW8 8 1像素1字节 1:1
RAW10 10 4像素5字节 4:5
RAW12 12 2像素3字节 2:3
RAW14 14 4像素7字节 4:7
RAW16 16 1像素2字节 1:2

3.3 长包与短包结构

CSI-2协议里,数据包分两种:长包和短包。长包用来传真正的像素数据,短包用来传控制信息,比如帧开始、帧结束、行开始、行结束。

长包的结构是这样的:

+----------------+----------------+----------------+----------------+
|  数据标识符(1B) |  字计数(2B)    |  数据负载(NB)  |  校验和(2B)    |
+----------------+----------------+----------------+----------------+
  • 数据标识符(Data Identifier):1个字节,高2位是虚拟通道号(Virtual Channel),低6位是数据类型(Data Type)。虚拟通道最多4个,可以同时传多路数据。
  • 字计数(Word Count):2个字节,表示数据负载的字节数。注意,这个计数不包括标识符和校验和。
  • 数据负载(Data Payload):真正的像素数据,长度由字计数决定。
  • 校验和(Checksum):2个字节,对数据负载做CRC校验。

短包的结构就简单多了:

+----------------+----------------+----------------+
|  数据标识符(1B) |  数据字段(2B)  |  校验和(2B)    |
+----------------+----------------+----------------+

短包没有数据负载,只有2个字节的数据字段。这个字段通常用来传帧号、行号之类的信息。比如帧开始包的短包,数据字段就是帧号。

注意:我曾经在调试时发现,有些传感器在传短包时,数据字段是0。一开始我以为传感器坏了,后来查手册才知道,它不支持帧号输出。所以,别把短包的数据字段当成必须有的信息,得看传感器支不支持。

3.4 ECC与校验机制

数据传输过程中,难免会有比特翻转。CSI-2用了两种校验机制来保证数据完整性:ECC和CRC。

ECC(Error Correction Code):用在包头上。长包和短包的数据标识符、字计数/数据字段,这3个字节(长包)或3个字节(短包)后面,跟着1个字节的ECC码。ECC能纠正1位错误,检测2位错误。

ECC的计算方式,说白了就是汉明码的一种变体。具体算法我就不展开了,你只要知道:驱动里收到一个包,先算ECC,如果发现1位错误,就自动纠正;如果发现2位错误,就丢弃这个包。

CRC(Cyclic Redundancy Check):用在数据负载上。长包的数据负载后面,跟着2个字节的CRC校验和。CRC只能检测错误,不能纠正。如果CRC校验失败,驱动就得丢掉这一整包数据。

我个人的建议是:调试阶段,把ECC和CRC的统计信息打印出来。如果发现ECC频繁纠正错误,说明物理层信号有问题,可能是走线太长、阻抗不匹配、或者时钟抖动太大。如果CRC频繁失败,那问题可能更严重,得检查电源、地线、或者传感器本身。

避坑指南:我曾经在一个项目里,图像偶尔出现条纹。查了三天,最后发现是ECC纠正了错误,但纠正后的数据还是错的——因为ECC只能纠正1位错误,而实际发生了2位错误。所以,别完全依赖ECC,它只是辅助手段。真正的可靠性,还得靠物理层的信号质量。

好了,这一章的内容就到这里。协议层架构是CSI-2的骨架,理解了它,你就能看懂驱动里那些包处理代码在干什么。下一章,咱们聊聊物理层D-PHY的电气特性和时序,那又是另一番天地了。