1. BLE 吞吐量基础概念

吞吐量,说白了就是单位时间内能传多少有效数据。很多工程师一上来就盯着物理层速率看,觉得 2Mbps 就是天花板。嗯,我刚开始做 BLE 项目时也这么想,结果实际测出来连 1Mbps 都跑不到。问题出在哪?

你想想看,物理层速率只是理论峰值,真正能传多少数据,还得看空中数据包怎么拼、连接间隔怎么设。这三者环环相扣,缺一个都算不清吞吐量。

1.1 物理层速率:不是你想跑就能跑

BLE 4.0/4.1 时代,物理层速率只有 1Mbps。到了 BLE 5.0,引入了 2Mbps 模式,速率直接翻倍。但注意,这只是「原始比特率」,不是有效数据速率。

BLE 版本 物理层速率 实际有效吞吐量(典型)
4.0/4.1 1 Mbps ~100-200 kbps
4.2 1 Mbps ~300-400 kbps(数据长度扩展)
5.0 2 Mbps ~600-800 kbps
5.2+ 2 Mbps ~1.2-1.4 Mbps(LE Audio 优化)

我在项目中遇到过客户拿着 2Mbps 的芯片,非要我保证 1.5Mbps 的吞吐量。我跟他解释:物理层速率是马路限速,但路上还有红绿灯、收费站、其他车辆。实际能跑多快,得看数据包结构和连接间隔。

关键点:物理层速率是上限,不是实际值。2Mbps 模式下,空中传输一个比特确实只需要 0.5μs,但协议栈开销、包间隔、处理延迟都会吃掉大量带宽。

1.2 空中数据包结构:每一比特都有代价

BLE 的空中数据包不是你想传什么就传什么。它有一套固定的格式。我习惯把数据包拆成三部分看:前导码 + 访问地址 + PDU。

以 BLE 5.0 的 2Mbps 模式为例,一个完整的数据包长这样:

| 前导码 (2字节) | 访问地址 (4字节) | PDU (2-257字节) | CRC (3字节) |
|----------------|------------------|-----------------|-------------|

PDU 内部又分:

| 头 (2字节) | 长度 (1字节) | 数据 (0-251字节) | MIC (4字节,可选) |
|------------|--------------|------------------|-------------------|

你看,真正能装用户数据的,只有 PDU 里的「数据」字段。其他全是开销。我算过一笔账:

  • 前导码 + 访问地址 + CRC = 9 字节固定开销
  • PDU 头 + 长度 = 3 字节
  • 如果启用加密,MIC 再吃掉 4 字节

也就是说,即使你传一个 251 字节的数据包,实际空中传输的字节数是 9 + 3 + 251 + 4 = 267 字节。有效载荷占比只有 251/267 ≈ 94%。

我的经验:BLE 4.2 引入了数据长度扩展(DLE),把 PDU 从 27 字节提升到 251 字节。这是吞吐量提升最大的一步。我有个项目,开启 DLE 后吞吐量直接从 80 kbps 跳到了 350 kbps。所以,第一件事就是检查你的芯片是否支持 DLE,并且是否默认开启。

1.3 连接间隔:吞吐量的节拍器

连接间隔是 BLE 连接中最重要的参数之一。它决定了主设备和从设备多久交换一次数据。

连接间隔的范围是 7.5ms 到 4s,步进 1.25ms。每个连接事件里,主设备会发送一个包,从设备回复一个包。但注意,一个连接事件里可以传多个包(这叫「连接事件内多包传输」)。

吞吐量的计算公式其实很简单:

吞吐量 = (每个连接事件传输的有效数据量) / (连接间隔)

举个例子:

  • 连接间隔设为 7.5ms
  • 每个连接事件传 6 个数据包(主发 3,从发 3)
  • 每个包有效数据 247 字节(开启 DLE 后)
  • 那么每秒吞吐量 = (6 × 247 × 8) / (7.5 × 10⁻³) ≈ 1.58 Mbps

看起来不错对吧?但实际跑不到。为什么?

避坑指南:我曾经把连接间隔设到 7.5ms,以为能跑满。结果发现从设备处理不过来,丢包率飙升。连接间隔越小,设备越忙。主设备发完包后,从设备要在 150μs 内回复(这叫 T_IFS)。如果从设备 CPU 太慢,或者有别的任务在跑,就会错过回复窗口,导致重传。重传一多,吞吐量反而下降。

我个人习惯,连接间隔不要低于 10ms。除非你的从设备是专用 BLE 芯片,没有其他任务干扰。否则 7.5ms 的间隔很容易翻车。

1.4 三者关系:一张图看懂

物理层速率、数据包结构、连接间隔,这三者不是独立的。我画了一张图,帮你理清它们的关系:

BLE 吞吐量三要素关系图 BLE 吞吐量三要素关系图 物理层速率 1Mbps / 2Mbps 数据包结构 PDU 27~251 字节 连接间隔 7.5ms ~ 4s 决定最大 传输速率 决定每包 有效载荷 实际吞吐量 = 每事件有效数据 / 连接间隔 关键结论 1. 物理层速率是天花板,但数据包结构决定你离天花板有多近 2. 连接间隔越小,吞吐量越高,但设备处理压力也越大 3. 开启 DLE(数据长度扩展)是性价比最高的优化手段 4. 三者需要平衡,不能只盯着一个参数调

1.5 实际项目中的取舍

说了这么多理论,来点实际的。我去年做一个医疗设备项目,需要把心电数据实时传到手机。要求吞吐量不低于 500 kbps。

我当时的配置是这样的:

  • 物理层:2Mbps(必须的)
  • DLE:开启,PDU 设为 251 字节
  • 连接间隔:15ms(不敢用 7.5ms,怕丢包)
  • 每个连接事件:传 4 个包(主 2,从 2)

算一下理论值:每个连接事件传 2 × 247 = 494 字节有效数据。每秒事件数 = 1000/15 ≈ 66.7。理论吞吐量 = 494 × 8 × 66.7 ≈ 263 kbps。

嗯,离 500 kbps 还差得远。怎么办?

我后来把连接间隔降到 10ms,每个事件传 6 个包(主 3,从 3)。理论值变成了 3 × 247 × 8 × 100 = 592 kbps。实际测下来 520 kbps 左右,达标了。

我的建议:调吞吐量时,先看连接间隔能不能降,再看每个事件能不能塞更多包。物理层速率是硬件决定的,一般改不了。数据包长度(DLE)基本是开关式的,开了就行。真正能调出花样的,就是连接间隔和事件内包数。

1.6 本章小结

吞吐量不是单一参数决定的。物理层速率是基础,数据包结构决定有效载荷,连接间隔控制传输频率。三者相乘,才是你真正能拿到的数据速率。

我见过太多人只盯着物理层速率看,结果实际跑出来只有十分之一。记住一句话:吞吐量 = 每事件有效数据 × 每秒事件数。把这两个因子拆开分析,问题就清晰了。