影响吞吐量的关键参数:PDU大小、连接间隔与LL层数据包长度扩展
吞吐量这东西,说白了就是「单位时间内能传多少有效数据」。很多工程师调了半天,发现速率上不去,其实问题就卡在几个关键参数上。我个人习惯先把这三个参数摸清楚——PDU大小、连接间隔、LL层数据包长度扩展。它们就像水管的口径、水龙头开关的频率,还有水管本身的材质,缺一个都跑不快。
1. PDU大小:数据包的有效载荷
PDU(Protocol Data Unit)是BLE协议栈里真正装数据的容器。你想想看,每次连接事件,主从双方交换的就是PDU。PDU越大,单次能携带的用户数据就越多。
核心结论:PDU大小直接决定了单次传输的「搬运效率」。默认的27字节PDU,刨去L2CAP和ATT的头部开销,用户数据只剩20字节。而扩展后的PDU最大可达251字节,用户数据能到244字节。
我在项目中遇到过一款穿戴设备,心率数据包每次只有18字节,用默认PDU完全够用。但后来要传固件升级包,一个512KB的bin文件,用20字节一包传,算下来要传两万多次。改成扩展PDU后,单包能塞244字节,传输次数直接降到两千多次——差了整整一个数量级。
| PDU类型 | 最大PDU长度 | 最大用户数据(ATT payload) | 适用场景 |
|---|---|---|---|
| 默认PDU | 27字节 | 20字节 | 传感器数据、状态通知 |
| 扩展PDU(DLE) | 251字节 | 244字节 | 固件升级、音频流、批量数据传输 |
实战技巧:并不是PDU越大越好。如果你的应用层数据本来就很小(比如温度传感器每次只发2字节),强行开大PDU反而浪费。我一般建议:单次数据量超过50字节,果断上DLE;低于20字节,保持默认即可。
2. 连接间隔:传输的节奏控制
连接间隔(Connection Interval)是BLE连接中两个相邻连接事件之间的时间间隔,单位是1.25ms的整数倍。范围从7.5ms到4s。这个参数决定了「多久能传一次数据」。
你想想看,PDU再大,如果连接间隔设成400ms,一秒只能传2.5次,吞吐量照样上不去。反过来,连接间隔设成7.5ms,一秒能传133次,就算PDU只有27字节,也能跑出2.6KB/s的速率。
注意:连接间隔越小,功耗越高。主从双方都要频繁唤醒收发数据。我曾经调试一个蓝牙耳机项目,为了追求低延迟把连接间隔压到7.5ms,结果耳机续航直接砍半。后来折中到30ms,延迟和功耗都还能接受。
连接间隔的选取有个经验公式:
理论最大吞吐量 ≈ (PDU有效载荷 × 每个连接事件的包数) / 连接间隔
举个例子:PDU开满251字节,连接间隔30ms,每个连接事件能传6个包(取决于LL层调度),那么理论吞吐量大约是:
244字节 × 6包 / 0.03s ≈ 48,800 字节/秒 ≈ 47.6 KB/s
嗯,这里要注意,实际吞吐量还要扣除协议开销、重传、调度延迟,一般能跑到理论值的60%-80%就算不错了。
3. LL层数据包长度扩展(LE Data Length Extension)
DLE是BLE 4.2引入的关键特性。它允许LL层数据包从默认的27字节扩展到251字节。说白了,就是让蓝牙协议栈底层能一次搬运更多数据。
我刚开始接触BLE时,以为只要在应用层把MTU设大就行。后来发现,如果LL层不支持DLE,应用层设再大的MTU也没用——底层一次只能传27字节,上层只能分片。这就像高速公路限速60km/h,你开再好的车也跑不快。
启用DLE的步骤:
- 确认主从双方芯片都支持BLE 4.2及以上
- 在连接建立后,主机发送LL_LENGTH_REQ PDU
- 从机回复LL_LENGTH_RSP,协商双方都支持的最大长度
- 协商成功后,后续所有数据包都使用扩展长度
实际项目中,我遇到过一种情况:从机芯片支持DLE,但固件里没开。结果主机发LL_LENGTH_REQ后,从机回复的长度还是27。折腾了半天才发现是SDK里有个宏定义没打开。所以我的建议是——连接建立后主动打印一下协商后的PDU长度,确认双方都跑在扩展模式下。
三个参数的联动关系
这三个参数不是孤立的。我画了一张图,帮你理清它们之间的逻辑:
从这张图能看出来,DLE是基础——没有它,PDU最大只能27字节,连接间隔再小也跑不快。PDU大小决定单次搬运量,连接间隔决定搬运频率。三者配合好了,吞吐量才能上去。
实际调优建议
我总结了一套调优流程,供你参考:
- 先确认硬件能力——主从芯片是否支持BLE 4.2+,是否支持DLE
- 启用DLE——连接建立后主动协商,打印协商结果确认
- 根据应用数据量选PDU——数据包大就开251字节,小就保持默认
- 根据延迟需求调连接间隔——对延迟敏感就设小(7.5ms-30ms),对功耗敏感就设大(50ms-100ms)
- 实测验证——用抓包工具看实际吞吐量,不要只看理论值
避坑指南:我曾经在一个项目中,主从双方都支持DLE,但协商后PDU长度只有27字节。查了半天发现是从机SDK里有个BLE_LL_DLE_ENABLE的宏默认是0。这种坑在国产芯片SDK里尤其常见,拿到新板子第一件事就是检查这个宏。