四、监控超时(Supervision Timeout)的原理与设置
监控超时,英文叫 Supervision Timeout,简称 STO。说白了,它就是 BLE 连接中最后一个兜底机制。
我刚开始搞 BLE 开发那会儿,总觉得只要连接参数设好了,链路就稳了。直到一次产品返修率飙升,排查了整整两周才发现,罪魁祸首竟然是监控超时设得太长。
什么是监控超时?
监控超时是连接双方用来检测链路是否断掉的定时器。如果主设备或从设备在规定时间内没有收到任何有效数据包(包括空的链路层包),就会认为连接已丢失,直接断开。
你想想看,空中的射频干扰再大,只要连接参数控制得好,数据包总能在重传机制下撑过去。但万一物理链路彻底断了呢?比如设备超出范围、电池耗尽、或者被人为挡住——这时候监控超时就会站出来,干净利落地结束连接。
原理拆解
BLE 协议栈里,监控超时的工作原理其实很简单:
- 每次成功收到一个包(ACK 也算),定时器就重置。
- 如果在
supervisionTimeout毫秒内没有任何包到达,触发超时事件,连接断开。
关键点在于:这个定时器是独立于连接间隔的。哪怕连接间隔是 100ms,监控超时也可以设为 4 秒。它更像一个“看门狗”,而不是“心跳”。
设置范围与规范
根据 BLE 核心规范 5.x,监控超时的取值范围是 10ms 到 32 秒,单位是 10ms 的倍数。但实际应用中,典型值集中在 1~6 秒。
我个人的习惯是:如果设备只在室内近场使用(比如智能手环),设 3~4 秒足够;如果是户外远距离场景(比如信标),我会设到 6~10 秒。为什么?因为物理环境干扰大,重传需要时间,超时设太短会误判。
| 场景 | 推荐监控超时 | 理由 |
|---|---|---|
| 近场室内(<5m) | 1~3 秒 | 链路稳定,误判风险低,断开响应快 |
| 室内中等距离(5~15m) | 3~6 秒 | 有轻微遮挡或移动,需容忍少量丢包 |
| 室外远距离(15m+) | 6~12 秒 | 信号衰减大,重传次数多,不能轻易断开 |
| 低功耗传感器(广播为主) | 8~15 秒 | 设备可能间歇休眠,但连接需要维持 |
监控超时与连接参数的配合
这是最容易踩坑的地方。我曾经遇到一个产品,连接间隔设 40ms,延迟设 8,监控超时设 2 秒。看起来没问题对吧?但实际测试发现,偶尔会有 2 秒多的无数据期,设备就断连了。
为什么?因为连接延迟(Slave Latency)让从设备可以跳过多个连接事件。假设延迟是 8,从设备最多可以 8 个连接事件不回复。40ms * 8 = 320ms,算上重传超时(最多 6 次重传,每次间隔翻倍),最坏情况下的无响应时长可能超过 1.5 秒,再加上别的微干扰,2 秒的 STO 就太紧了。
我建议的匹配公式是这样的:
Safe Supervision Timeout > (连接间隔 × (Latency + 1) × 2) + 额外余量
举个实际例子:连接间隔 30ms,延迟 4,那么最快能让链路的 ping 间隔是 30×(4+1)=150ms。乘以 2 是 300ms。加上余量(射频干扰、重传等),我一般再加 1~2 秒。所以最终设 1.5~2 秒是合理的。
监控超时与“频繁泄漏”的关系
回到课程主题——连接参数导致 BLE 泄漏。监控超时本身并不直接导致泄漏,但它会放大其他参数的问题。
- STO 太短:微弱干扰就断连,然后设备立即重连,重连过程会产生大量广播和扫描请求,造成空口拥塞——这就是“泄漏”的一种表现。
- STO 太长:链路已经断了,但双方以为还连着,会一直等下去。这时候应用层可能发起无意义的读写操作,产生垃圾数据包,也是泄漏。
说白了,监控超时不合适,就像家里的煤气报警器设得太灵敏或太迟钝——都会出问题。
如何排查监控超时相关泄漏
我的排查套路是三步走:
- 抓空口日志:用 ELLISYS 或 Nordic Sniffer 抓一段连接过程。查看是否有大量重复的连接请求(Link Layer CONNECT_REQ),或者连接断开后立即重新建立。
- 检查连接间隔与 STO 的比值:如果 STO < 连接间隔 × (Latency+1) × 2.5,就有误断风险。
- 看设备端的超时统计:多数 BLE 芯片有寄存器记录超时次数。我见过一个项目,每天超时 300 次,调大 STO 后降到个位数。
我曾经在一个 IoT 网关项目中,客户抱怨丢包严重。我打开抓包工具一看,发现每 2~3 秒就断连重连一次,空口上全是广播包。最后发现是 STO 设了 1.5 秒,而连接间隔 100ms、延迟 10。算一下就知道了,最坏响应间隔是 100×(10+1)=1100ms,差点超时。调大到 3 秒后,问题消失了。
SVG 图:监控超时工作原理与排查流程
下面这张图总结了我上面讲的核心逻辑:监控超时的触发条件、与连接参数的配合、以及排查导图。
常见误区与避坑
我曾经见过有人把 STO 设到 30 秒,以为能避免断连。结果设备断开后应用层 30 秒后才感知到,用户体验极差。而且空口上的重传包一直累积,导致其他连接也受影响。
正确做法: 根据实际链路最差延迟设一个合理的上限,通常不超过 10 秒。
如果只调 STO 不调 Latency,就像只加长绳子不调整结扣。我建议在调试时先用抓包工具记录一段正常的“无包间隔”曲线,然后让 STO 比这个间隔大 2~3 倍即可。
另外,要注意不同芯片厂商的实现差异。有的芯片在 STO 超时后不会立即释放射频资源,还会发几次重连请求,造成额外泄漏。排查时可以留意硬件手册里关于 STO 行为的部分。
嗯,监控超时就讲到这里。记住一句话:它是一道安,不是一根救命稻草。设对了能防泄漏,设错了反而制造泄漏。