上个月帮一个做工业数据采集的团队看问题,他们用一套自研的无线轮询协议,主站每隔两秒向从站发一轮广播包,从站收到后回传采集数据。现场跑了三个月一直正常,突然有一天主站日志里开始出现大量“广播发出后无回应”的告警,但换一台备机接上去就没事。他们把主站设备返厂检测,硬件指标全过,软件逻辑逐行比对也没找出差异。折腾了快两周,最后发现是机房新装了一台大功率变频设备,它的传导骚扰从供电线路串进了主站设备的电源入口,导致射频前端在广播包发出后的那个时间窗口里噪声底噪抬高了十几个dB,把从站回传的微弱信号淹没了。备机因为电源滤波设计略有不同,恰好扛住了。
这件事让我觉得有必要把“广播包发出后没有回应”这个现象单独拎出来讲一讲。它太常见了,常见到很多人第一反应就是“从站没收到”或者“从站没回复”,然后一头扎进协议解析里出不来。但实际工程中,这个现象背后的链路问题远比协议本身复杂,而且公开资料里很少有人把排查顺序和判断依据讲透。
先确认“没有回应”是谁的视角
主站软件报“无回应”,这个“无回应”至少有三个不同的观察层面,混在一起谈就会乱。
第一层是主站射频收发器层面:广播包到底有没有被真正发射出去。很多主站软件调用发送接口后立刻开始计时等待,但射频芯片可能因为前一次收发切换还没完成、或者信道忙检测未通过,导致这次发送请求被内部排队甚至丢弃。软件层面看到的是“我调用了发送”,射频层面看到的是“我还没发”。这时候从站当然不会回应,因为空中根本没有这个包。
第二层是空中接口层面:广播包发出去了,但从站没收到,或者收到了但解调失败。广播包通常没有应答机制,从站即使收到一个CRC校验失败的包,也只能默默丢弃,主站无从知晓。
第三层是从站应用层面:从站正确收到了广播包,但决定不回复。比如从站正处于低功耗休眠周期、或者它的回复被自己的协议栈延迟了、或者它回复了但主站没收到。
排查的第一步,就是先确定问题卡在哪一层。不要一上来就抓空中包,也不要一上来就改从站代码。
用射频收发器的状态寄存器做第一道分水岭
如果你用的射频收发器有状态寄存器可以读回发射完成标志、信道忙标志、以及发射FIFO空中断标志,那事情就好办很多。广播包发出后无回应,先读这几个状态。
一个典型的坑是:主站软件在发送广播包之前,刚刚完成了一次接收。射频收发器从接收模式切到发射模式需要一定的时间,这个时间在数据手册里通常写作“收发切换时间”,但实际工程中它受温度、供电电压、外部匹配网络的影响,可能比标称值大不少。如果软件在切换完成之前就写入了发射FIFO并触发发送,射频芯片内部可能直接忽略这次触发,或者把数据压进FIFO但迟迟不发射。这时候读状态寄存器,会看到发射完成标志一直不置位,而软件那边的超时计时已经跑完了。
现场怎么观察:在发送广播包之前加一段延时,或者轮询射频收发器的“就绪”状态位,等它真正进入发射就绪态再写FIFO。如果加延时后问题消失,基本可以确定是收发切换时序的问题。但延时加多少合适,不能拍脑袋,要看射频收发器数据手册里的最坏情况切换时间,再留一倍余量。
另一个隐形陷阱是信道忙检测。很多射频收发器在发射前会自动做一次信道能量检测,如果检测到当前信道能量超过某个阈值,它会认为信道被占用,从而延迟发射或者直接放弃发射。这个机制在CSMA类协议里是好事,但在广播轮询场景下可能是灾难——因为主站附近可能有一个持续发射的干扰源,导致主站每次想发广播都被自己的信道忙检测拦住。这时候从站当然收不到任何东西。读状态寄存器会看到“信道忙”标志置位,而发射完成标志始终不置位。
现场排查方法:临时关闭信道忙检测功能,或者把信道忙阈值调到最高,看广播包是否能正常发出。如果关闭后从站开始回应,说明问题出在信道忙检测被干扰触发。但注意,关闭信道忙检测只是诊断手段,不能作为最终方案,否则会带来同频碰撞风险。最终方案要么是换信道,要么是找到干扰源并消除它。
空中包抓取的正确姿势
如果射频收发器状态显示广播包已经成功发射,那就要看空中了。抓空中包这件事,很多人以为只要把抓包设备调到相同频点就能看到,实际远没那么简单。
第一个坑是抓包设备的接收带宽和主站发射信号的带宽不匹配。主站射频收发器可能设置了某种调制方式和符号速率,占用一定的带宽。如果抓包设备的接收带宽比这个窄,或者中心频点有偏差,抓到的包可能严重失真,甚至完全解调不出来。你会误以为主站没发,实际上主站发了,只是抓包设备没抓好。
第二个坑是抓包设备的触发时机。广播包是周期性发出的,间隔可能只有几百毫秒甚至更短。如果抓包设备是手动触发抓取,很可能错过。正确做法是用主站发送完成信号去触发抓包设备,或者让抓包设备连续抓取足够长的时间窗口,覆盖至少十几个广播周期。
第三个坑更隐蔽:抓包设备本身在接收时,如果主站和从站距离很近,主站发射的强信号可能使抓包设备的前端饱和,产生阻塞。阻塞期间抓包设备什么都收不到,包括从站的回应。你会看到主站广播包正常,但从站回应完全消失,误以为从站没回。实际上从站回了,只是抓包设备被主站信号堵住了。
现场怎么判断是不是阻塞:把抓包设备的天线衰减器加上,或者把抓包设备移到离主站稍远的位置,同时保持能收到从站信号。如果加上衰减后从站回应出现了,基本可以确定是抓包设备前端饱和。
从站“收到但不回”的几种常见原因
如果空中抓包确认主站广播包正常发出,从站也确实收到了这个包,但从站没有回应,那问题就在从站侧。从站收到广播包后不回应,常见原因有这么几类。
第一类是地址过滤。广播包通常有一个目标地址字段,从站会检查这个字段是否匹配自己的地址或者广播地址。如果主站软件在组包时把目标地址写错了,或者从站的地址配置和主站记录的不一致,从站会直接丢弃这个包,不会回应。这种问题在更换从站或者修改地址后特别容易出现。现场排查方法是把从站接到调试串口上,看它有没有打印“收到包但地址不匹配”之类的日志。如果没有日志,可以用一个已知能正常回应的从站替换上去,如果替换后正常,说明是原从站的地址配置问题。
第二类是广播包长度和从站预期不符。有些从站的协议栈对广播包长度有硬性检查,比如固定长度或者长度必须在某个范围内。主站如果因为固件升级或者配置变更导致广播包长度变了,从站可能直接丢弃。这种问题往往在主站单方面升级后出现,从站没动,所以容易被忽略。
第三类是从站的回复被自己的低功耗调度延迟了。如果从站处于休眠唤醒周期中,它可能收到了广播包,但射频收发器处于休眠状态,协议栈把回复排队到下一个唤醒窗口才发送。如果主站的等待超时时间比从站的休眠周期短,就会报无回应。现场观察方法:把主站的等待超时时间临时延长到从站休眠周期的两倍以上,看是否能收到回复。如果能收到,说明是从站休眠调度的问题,需要调整主站超时或者从站唤醒策略。
第四类是从站的发射被自己的信道忙检测拦住了。和主站类似,从站回复之前也可能做信道忙检测。如果从站附近有干扰源,从站可能一直无法回复。这种问题的特点是:主站广播包正常,从站日志显示“收到广播包,准备回复”,然后就没有然后了。读从站射频收发器状态寄存器会看到信道忙标志置位。
链路余量和干扰的现场判断
广播包发出后无回应,如果排除了以上所有逻辑问题,最后一定要回到链路余量上来。很多“时好时坏”的无回应,本质上是链路余量不够,在临界点附近波动。
链路余量不够的典型表现是:距离近的时候正常,距离远的时候偶尔无回应;或者白天正常,晚上无回应;或者设备刚上电正常,跑一段时间后无回应。这些现象都指向同一个原因——接收信号强度在接收灵敏度附近波动,偶尔低于灵敏度就丢包。
现场判断链路余量的方法:在主站和从站分别读取接收信号强度指示值。如果主站广播包发出后,从站收到的信号强度比从站接收灵敏度只高几个dB,那链路余量就太少了。工程上一般建议留20dB以上的余量,考虑温度变化、天线方向、多径衰落等因素。
但这里有一个很容易被忽略的陷阱:接收信号强度指示值是在解调前测量的,它反映的是整个接收带宽内的总能量,包括有用信号和噪声。如果信道里有干扰,接收信号强度指示值可能很高,但信噪比很差,解调照样失败。所以不能只看接收信号强度指示值,还要看信噪比或者误包率。
现场快速判断干扰的方法:把主站和从站都设置成持续接收模式,用频谱分析仪或者带频谱功能的抓包设备看信道底噪。如果底噪比正常情况高很多,说明有干扰。然后关掉附近可能产生干扰的设备,看底噪是否降下来。如果降下来且通信恢复,干扰源就找到了。
一个容易被忽略的时序陷阱
最后讲一个我踩过的坑,这个坑在公开资料里几乎没人提。
主站发出广播包后,射频收发器需要从发射模式切回接收模式,才能接收从站的回应。这个切换需要时间,而且切换过程中射频收发器是“聋”的。如果从站收到广播包后回复得非常快,快到在主站完成收发切换之前就把回应发出来了,那主站就会错过这个回应,软件层面看到的就是“无回应”。
这个问题的诡异之处在于:从站越“听话”、回复越快,主站越收不到。反而从站如果回复慢一点,等主站切换完成后再发,主站就能收到。所以你会看到一种反常现象——优化从站代码让它更快回复,结果无回应告警反而增多了。
现场判断方法:用抓包设备同时抓主站广播包和从站回应包,测量从站回应包相对于主站广播包结束的时间差。然后查主站射频收发器的收发切换时间。如果从站回应到达时刻落在主站收发切换窗口内,那就是这个问题。解决办法要么是让从站延迟一个固定时间再回复,要么是主站换用支持快速收发切换的射频收发器,要么是在协议里把回应时机往后挪。
这个坑之所以难查,是因为它不像丢包那样随机,而是稳定地发生在每一个广播周期里。主站日志会显示“每一个广播包都无回应”,但抓包又能看到从站确实回了。如果抓包设备只抓主站发射、不抓从站回应,或者抓包设备离主站太近被阻塞,就很容易误判为从站没回。
排查顺序的取舍
把上面这些串起来,广播包发出后无回应的排查顺序应该是:
先读主站射频收发器状态寄存器,确认广播包是否真正发射成功,排除收发切换和信道忙检测的问题。这一步不需要任何额外设备,成本最低。
然后用抓包设备确认空中是否有广播包,以及从站是否有回应。抓包时注意接收带宽、触发时机、前端饱和这三个坑。
如果空中确认从站有回应但主站收不到,查主站收发切换时序和接收窗口配置。
如果空中确认从站无回应,查从站地址过滤、包长度检查、休眠调度、信道忙检测。
最后如果以上都正常但问题偶发,查链路余量和干扰,看接收信号强度指示值和信噪比,用频谱看底噪。
这个顺序的核心逻辑是:从主站到空中再到从站,从确定性高的检查到确定性低的检查,从不需要额外设备的检查到需要额外设备的检查。不要跳步,不要凭直觉直接怀疑从站,也不要一上来就抓空中包。每一步的结论都是下一步的输入,跳步会导致误判。
广播包无回应这个问题,表面上看是通信问题,实际上牵扯到射频时序、协议状态机、电源质量、电磁环境多个层面。把排查顺序理清楚,比掌握任何一个单独的技术点都重要。