4. MAC层问题排查:时隙同步失败、帧冲突、ACK超时、退避算法异常
各位工程师,咱们继续往下聊。UWB的MAC层,说白了就是无线通信的交通警察。它管着谁什么时候说话、说多久、说完怎么确认。这一层要是出问题,物理层信号再好也白搭。我见过太多项目,天线调得漂漂亮亮,测距精度做到厘米级,结果连接就是断断续续——最后查出来,全是MAC层在捣鬼。
今天咱们就聚焦四个最头疼的MAC层故障:时隙同步失败、帧冲突、ACK超时、退避算法异常。这四个问题经常串在一起,一个没处理好,连锁反应就来了。
核心观点:MAC层故障的排查,一定要从时序入手。先看同步,再看冲突,最后查退避。顺序错了,你可能会绕很多弯路。
4.1 时隙同步失败:一切问题的根源
UWB的MAC层大多采用TDMA(时分多址)机制。每个设备分配一个时隙,在自己的时隙里发数据,其他时间闭嘴听。这个机制的前提是什么?所有设备的时间基准必须一致。一旦时钟漂移,时隙错位,整个网络就乱套了。
时隙同步失败的典型表现:
- 设备能收到信标帧,但始终无法加入网络
- 加入网络后频繁掉线,掉线间隔有规律(比如每几分钟一次)
- 测距结果偶尔出现巨大跳变(比如从1米跳到100米)
我个人习惯,排查同步问题时先看两个参数:时钟精度(ppm)和同步间隔。这两个参数是配套的,一个决定漂移速度,一个决定校正频率。
| 时钟精度(ppm) | 最大漂移(1秒内) | 建议最大同步间隔 |
|---|---|---|
| ±20 ppm | ±20 μs | ≤ 500 ms |
| ±10 ppm | ±10 μs | ≤ 1 s |
| ±5 ppm | ±5 μs | ≤ 2 s |
| ±2 ppm | ±2 μs | ≤ 5 s |
我的经验:很多开发板用的晶振是±20 ppm的,便宜嘛。但如果你把同步间隔设成2秒,漂移就能到±40 μs。UWB的时隙宽度通常只有几十微秒,这么漂下去,不出10个周期,时隙就撞上了。我建议,量产产品至少用±10 ppm的温补晶振,同步间隔不要超过1秒。
排查步骤:
- 用逻辑分析仪抓取信标帧的发送间隔,看是否稳定
- 在从设备端打印本地时间与信标时间戳的差值,看漂移趋势
- 检查同步算法是否考虑了传播时延(特别是远距离场景)
- 验证晶振实际频率——用频谱仪测一下,别信数据手册
注意:我曾经遇到一个案例,晶振标称±10 ppm,实际测出来±35 ppm。原因是电源纹波太大,导致晶振抖动。所以,同步问题不一定是算法问题,也可能是电源问题。先量一下供电质量,别急着改代码。
4.2 帧冲突:当两个设备同时说话
时隙同步做好了,帧冲突的概率会大大降低。但注意,我说的是「降低」,不是「消除」。为什么?因为UWB网络里还有异步接入的机制,比如随机接入时隙、信标帧的竞争期。这些场景下,两个设备同时发帧,冲突就来了。
帧冲突的典型特征:
- 丢包率呈突发性增长,不是均匀分布
- 丢包集中在某个特定时隙或特定设备
- 增加设备数量后,丢包率非线性上升
排查帧冲突,我一般用三步法:
- 看冲突窗口——检查MAC层配置,确认哪些时隙是竞争接入的,哪些是专用时隙。竞争时隙越多,冲突概率越大。
- 算冲突概率——如果N个设备在同一个竞争时隙窗口里随机选择发送时机,冲突概率可以用公式估算。简单说,设备越多、窗口越小,冲突越严重。
- 抓实际冲突——用双通道逻辑分析仪,同时抓两个设备的发送引脚。如果它们的发送信号在时间上重叠,那就是实锤了。
一个实用的经验值:竞争时隙的窗口长度,建议设置为设备数量的2~3倍。比如网络里有10个设备,竞争窗口至少设20个时隙。低于这个比例,冲突概率会急剧上升。
嗯,这里还要提一个容易被忽略的点:隐藏节点问题。两个设备互相看不见,但都能和基站通信。它们各自以为信道空闲,同时发帧,基站那边就冲突了。UWB虽然抗干扰能力强,但帧冲突是MAC层的事,物理层再强也救不了。
4.3 ACK超时:发了没人理
ACK超时,说白了就是:我发了帧,等了好久没收到确认。UWB的MAC层通常有ACK机制,发送方会在发送后开启一个定时器,如果在超时时间内没收到ACK,就认为帧丢失了。
ACK超时的原因,我归纳为三类:
| 原因分类 | 具体表现 | 排查方向 |
|---|---|---|
| 帧根本没到 | 接收方没收到任何信号 | 物理层链路、发射功率、天线 |
| 帧到了但解不出来 | 接收方收到信号但CRC校验失败 | 干扰、多径、帧格式错误 |
| ACK帧丢了 | 接收方发了ACK,但发送方没收到 | 双向链路不对称、ACK优先级低 |
我个人排查ACK超时,会先看超时时间设置。很多工程师直接把超时时间设成固定值,比如5 ms。但UWB的传播时延和收发切换时间,在不同距离下差异很大。近距离1米,传播时延才3 ns,远距离100米就是333 ns。再加上收发切换时间、处理时间,5 ms可能太紧,也可能太松。
我的建议:ACK超时时间应该动态计算。公式很简单:超时时间 = 2 × 传播时延 + 收发切换时间 + 处理时间 + 安全余量。安全余量建议加20%~30%。我曾经在一个项目中,把固定超时改成动态计算,ACK超时率从15%降到了0.5%以下。
另外,别忘了检查ACK帧的优先级。有些MAC实现里,ACK帧和普通数据帧共用同一个发送队列。如果队列里积压了数据帧,ACK就得排队,一排队就超时了。我建议,ACK帧应该使用独立的、高优先级的发送通道。
4.4 退避算法异常:越退越乱
退避算法,是MAC层用来处理冲突后的「冷静机制」。发帧冲突了,双方各自随机等一段时间再重发。这个机制本身没问题,但实现起来容易出幺蛾子。
退避算法异常的常见表现:
- 重发次数急剧增加,但重发成功率很低
- 设备长时间不发送任何帧(退避时间过长)
- 多个设备退避时间同步,导致反复冲突
我遇到过最典型的案例,是退避算法的随机数种子出了问题。某个芯片的随机数生成器,在复位后总是产生相同的种子序列。结果呢?两个设备同时冲突,同时退避,退避时间一模一样,然后同时重发——又冲突了。死循环。
避坑指南:我曾经在一个项目中,发现退避后的重发成功率只有30%。查了两天,最后发现退避算法的指数退避上限设成了255个时隙。网络里只有5个设备,退避255个时隙纯属浪费。退避窗口的上限应该根据网络规模动态调整。设备少,窗口小一点;设备多,窗口大一点。
退避算法参数检查清单:
- 最小退避窗口(CWmin):建议设为竞争时隙数的1~2倍
- 最大退避窗口(CWmax):建议不超过竞争时隙数的16倍
- 退避指数:标准是二进制指数退避(每次冲突翻倍),但不要无限翻倍
- 随机数质量:验证随机数生成器是否产生均匀分布
- 退避计数器重置条件:成功发送后是否及时重置
还有一个细节,很多人不注意:退避时间是从什么时候开始算的?有些实现是从冲突发生时刻开始算,有些是从检测到信道空闲开始算。这两种算法在连续冲突场景下,行为差异很大。我个人倾向于后者——检测到信道空闲再开始退避,能有效减少连续冲突的概率。
总结一下:MAC层的四个问题,时隙同步是地基,帧冲突是表象,ACK超时是结果,退避异常是放大器。排查时按这个顺序走,能省不少时间。别一上来就调退避参数,先看看同步稳不稳。同步不稳,后面调再多也是白费功夫。