链路层数据包格式:帧结构、字段定义

调试UCIe链路层,最基础的就是搞清楚数据包长什么样。我刚开始接触UCIe时,对着协议文档看了三天,还是一头雾水。后来在实验室里抓了一次波形,把每个字段和文档一一对应,才算真正理解。说白了,帧结构就是你从逻辑层往下扔东西,链路层给它套上一层层的外壳。

帧结构总览

一个完整的UCIe链路层数据包,从帧起始到帧结束,通常包含下面这些字段。注意,不是所有字段都是必须的,具体看配置。

核心观点: 链路层数据包 = 头部(控制信息)+ 数据负载 + 尾部(校验保护)。拆包时按顺序解析就行。

UCIe链路层数据包帧结构 SOP 2字节 Rsv 1B CT + VN 2B Protocol 1B SeqNum 1B Vendor 1B Payload 0~64B CRC 2~4B EOP 2字节 帧头部(SOP为主) 数据域 帧尾部

各字段详解

SOP / EOP(帧起始/结束定界符)

每个包由SOP开始,EOP结束。我在调试时发现,有时候链路层报CRC错误,根源却是EOP位置不对。你想想看,EOP被截断或丢失,整个包都会被当作无效。

  • SOP:编码模式为0xFB(K码),表示一个包开始。
  • EOP:编码模式为0xFD(K码),表示包结束。
  • 这两个字段不参与CRC计算,但物理层必须正确识别。

小技巧: 用逻辑分析仪抓SOP/EOP时,注意K码抑制(Comma)的极性——我曾经因为差分线极性接反,导致SOP一直通不过,折腾了一整天。

保留字段(Rsv)

1字节,一般填0。但有些IP供应商会用它传递内部调试信息。如果你看到非零值,先查供应商文档。

Cycle Type + Virtual Network(CT+VN)

2字节,控制包的类型和所属的虚拟网络。CT决定包是 请求、响应 还是 数据,VN则用于隔离不同QoS流量。

Cycle Type含义典型长度
00Request(非投递)可变
01Request(投递)可变
10Response可变
11Data64B居多

Protocol(协议类型)

1字节,标识上层是什么协议。比如0x00表示流控(FC),0x01表示原始内存语义。嗯,这里要注意:这块定义和协议栈关系很大,不同厂家可能自定义。

Sequence Number(序列号)

1字节,从0累加,用于重排序和丢包检测。我曾在项目中看到序列号跳变3次后才触发链路层重传——后来发现是重传超时设得太长。

Vendor Define(厂商自定义)

1字节,留给芯片厂商放私有信息。调试时如果遇到不明白的包,先看这个字段。有时厂商会用它做debug Tag。

Payload(数据负载)

长度0~64字节。注意,如果是流控报文(FC),Payload为0。数据报文最大64B,超过的话需要切包。

CRC(循环冗余校验)

长度2~4字节,覆盖整个包(不含SOP/EOP)。我习惯先在仿真环境里故意篡改一位CRC,看看链路层能不能正确报告错误——这是一个不错的边界测试手段。

避坑指南: 有的SoC为了省功耗,把CRC改成2字节(CRC-16)。如果你抓取的包CRC长度是4字节,而期望是2字节,八成是配置不一致。我曾经在这个坑里浪费了一周,最后发现是寄存器没切到正确模式。

调试中的关键字段

平时看包,重点盯这几个位置:

  1. SOP/EOP——包完整性
  2. Sequence Number——丢包与乱序
  3. CRC——传输完整性
  4. CT+VN——包类型和QoS归属

举个例子:如果Sequence Number不连续,但CRC没错,那多半是中间某个包被链路层丢弃了(可能是流控反压导致溢出)。这时候要去查Credit机制。

格式对比:Standard vs Optional

UCIe 1.0定义了两种帧格式:Standard(标准)和Optional(可选)。区别主要在Vendor Define和保留字段的安排上。

特性StandardOptional
保留字段固定1字节可被复用为扩展ID
自定义字段有(1字节)有(1字节)
最大负载64B64B
兼容性所有设备必须支持可选项,需双方约定

个人建议:初期调试全部用Standard格式,少踩兼容性的坑。等链路稳定了,再考虑用Optional格式压性能。