3. UniPro数据链路层(L2):数据链路层功能概述、帧结构、流量控制、重传机制与状态机
各位同学,今天我们聊聊UniPro协议栈里最“接地气”的一层——数据链路层,也就是L2。说实话,很多做芯片验证的朋友,一开始接触UniPro都会被物理层(L1)的M-PHY搞得头大,但真正决定链路能不能稳定跑起来的,其实是L2。我个人习惯把L2比作一个“交通指挥官”——它不关心数据是什么内容,只关心数据怎么安全、有序地到达对端。
3.1 数据链路层功能概述
L2层在UniPro协议栈里,夹在物理层(L1)和网络层(L3)之间。它的核心任务就四个字:可靠传输。你想想看,物理层只管发比特流,万一中间丢了一个包,或者顺序乱了,上层根本不知道。L2就是来解决这个问题的。
具体来说,L2干了这几件事:
- 成帧(Framing):把上层的数据包封装成固定格式的帧,加上头尾和校验。
- 差错检测:通过CRC校验,判断帧在传输过程中有没有被“污染”。
- 流量控制(Flow Control, FC):防止发送方太快,把接收方“撑死”。
- 重传机制(Automatic Repeat-reQuest, ARQ):发现错误帧,自动请求重发。
- 链路管理:维护链路的状态机,比如什么时候该激活,什么时候该休眠。
我在项目中遇到过一个问题:某次调试时,发现链路偶尔会卡死,数据发不出去。查了半天,最后发现是L2的流量控制计数器配置错了,导致接收方明明还有空间,却告诉发送方“满了”。嗯,这种坑,不踩一次真的记不住。
3.2 帧结构:帧头、帧尾与CRC校验
L2的帧结构,说白了就是一套“信封”。信封外面写清楚谁发的、发给谁、多长,信封里面才是真正的数据。UniPro L2的帧结构大致如下:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 帧头(Frame Header) | 4 | 包含帧类型、序列号、长度等信息 |
| 有效载荷(Payload) | 0~4095 | 上层传下来的数据 |
| 帧尾(Frame Trailer) | 2 | CRC校验值 |
帧头里最重要的几个东西:
- 序列号(Sequence Number):每个帧都有一个唯一的序号,接收方靠它判断有没有丢帧。
- 帧类型:区分是数据帧还是控制帧(比如ACK、NACK)。
- 长度字段:告诉接收方这个帧有多长,方便解析。
帧尾的CRC校验,我建议你把它当成“指纹”。发送方计算整个帧的CRC值,附在末尾。接收方收到后重新算一遍,如果对不上,说明帧在传输过程中被篡改了。CRC-16是UniPro L2的标准,虽然不如CRC-32那么强,但对于芯片内部短距离传输来说,已经足够了。
3.3 流量控制机制(FC)
流量控制,说白了就是“你慢点发,我快吃不消了”。UniPro L2用的是基于信用的流量控制(Credit-based Flow Control)。接收方会告诉发送方:“我还能收多少个帧”,发送方就按这个额度发,发完了就等。
具体流程是这样的:
- 链路建立后,接收方通过控制帧告诉发送方自己的接收缓冲区大小(初始信用)。
- 发送方每发一个帧,就消耗一个信用。
- 接收方处理完一个帧后,会返还一个信用(通过FC帧)。
- 发送方信用为0时,必须停止发送,直到收到新的信用。
你可能会问:“为什么不直接用停等协议(Stop-and-Wait)?” 嗯,停等协议效率太低了,发一个等一个,带宽利用率上不去。基于信用的方式可以连续发多个帧,只要信用够,效率高很多。
3.4 重传机制(ARQ)
重传机制,是L2保证可靠性的最后一道防线。UniPro L2用的是选择性重传(Selective Repeat ARQ)。什么意思呢?就是接收方发现某个帧错了,只要求重传那一个,而不是把后面的全部重传。
工作流程:
- 发送方连续发送多个帧,每个帧都有唯一的序列号。
- 接收方收到帧后,检查CRC。如果正确,回复ACK(确认帧);如果错误,回复NACK(否定确认帧)。
- 发送方收到NACK后,只重传那个出错的帧。
- 接收方收到重传的帧后,按序列号重新排序,然后交给上层。
这里有个关键点:超时重传。如果发送方发了一个帧,等了很久都没收到ACK或NACK,它会认为这个帧丢了,自动重传。超时时间怎么设?设短了容易误重传,设长了影响性能。我一般建议设成“最坏情况下的往返时间(RTT)乘以1.5”。
3.5 链路层状态机
L2的状态机,是控制链路生命周期的大脑。UniPro L2的状态机主要有以下几个状态:
- INACTIVE(未激活):链路未建立,不发送任何数据。
- ACTIVATION(激活中):正在建立链路,交换配置参数。
- ACTIVE(已激活):链路正常工作,可以收发数据。
- DEACTIVATION(去激活中):正在关闭链路,释放资源。
- ERROR(错误):检测到不可恢复的错误,需要复位。
状态转换的触发条件包括:上层的请求、物理层状态变化、超时、错误检测等。比如,当物理层报告“信号丢失”时,L2会从ACTIVE跳转到ERROR状态,然后尝试重新激活。
下面是我画的一张L2状态机简图,帮你直观理解:
状态机的验证,我个人觉得是L2验证里最复杂的部分。因为状态转换往往涉及多个条件同时满足,比如“收到ACK且信用大于0且链路未超时”。我建议你用状态覆盖(State Coverage)和转换覆盖(Transition Coverage)来确保每个状态和每条转换路径都被测试到。
好了,关于UniPro数据链路层的内容,今天就先聊到这里。L2是协议栈里承上启下的关键一层,帧结构、流量控制、重传机制和状态机,每一个都值得你花时间深入理解。下次我们聊聊网络层(L3),看看数据是怎么在多个设备之间路由的。
公众号:蓝海资料掘金营,微信deep3321