本文BLE传输速率指传输图片等应用数据的速率。一般计算的是RX速率。
本文从协议的角度分析影响BLE传输速率的因素有哪些以及如何提高。

1 协议分析

1.1 BLE的物理层

BLE工作频率是2.4GHz,它使用GFSK频率调制,分为40个信道,并使用跳频机制来解决频道拥挤问题。

物理层实现方案

符号速率

编码方案

比特率

备注

LE 1M Uncoded PHY

1Msym/s

无编码

1Mb/s

BLE v4系列协议;强制;

LE 2M Uncoded PHY

2Msym/s

无编码

2Mb/s

提高通信速率;可选;

LE 1M Coded PHY

1Msym/s

编码S=2;编码S=8

500kb/s;125kb/s

提高通信距离;可选;

BLE4只支持第一种,BLE5支持三种。目前大多BLE设备还是使用第一种,第二种第三种需要双方都支持,才能用。
注:这里的比特率指的是模组的发射速率,并不是指BLE的最大传输速率,但它是影响BLE传输速率因素之一。

1.2 数据包格式

为了更好地了解影响应用程序吞吐量的因素,我们必须更深入地了解数据包格式。下图显示了 LE 1M PHY 和 2M PHY 数据包的组成:

Android开发 提升蓝牙传输速率 如何提升蓝牙传输速度_链路


我们感兴趣的部分(真正定义应用程序数据的部分)是ATT Payload。 从图中可以看出,蓝牙低功耗中的每一层都使用了许多额外开销字节。

在4.0和4.1中,最大ATT有效载荷为20个字节。
在4.2和5.0中,称为数据长度扩展(DLE)的新功能允许ATT有效载荷最多可容纳244个字节的数据。

1.3 BLE连接传输原理说明

主设备和从设备建立连接之后,所有的数据通信都是在连接事件(Connection Events)中进行的。

Android开发 提升蓝牙传输速率 如何提升蓝牙传输速度_数据_02


下面看BLE连接传输的一个例子,其中每个连接间隔里包含6个主机和6个从机的 Link Layer Packet;如果每个 Link Layer Pakcet 限制最多包含 20 字节用户数据,那么每次 Connection Interval, BLE主机最多可以发送 120 字节用户数据, BLE 从机最多可以发送 120 字节用户数据。

Android开发 提升蓝牙传输速率 如何提升蓝牙传输速度_ci_03

2 影响BLE速率的因素有哪些

1.使用的 PHY(LE 1M 与 LE 2M 与 LE 编码(S=2 或 S=8))
2.数据包开销——并非数据包中的所有字节都用于有效载荷
3.数据长度扩展 (DLE)
4.ATT 最大传输单元 (ATT MTU)
5.数据包占比—连接间隔
6.数据包占比—每个连接间隔的最大数据包数(某些设备有一定限制)
7.帧间隔 (IFS):数据包之间的时间间隔 (150 us)
8.操作类型:有响应的写入与无响应的写入,指示与通知

这里解释一下第4点,为什么ATT MTU影响,比如ATT_MTU最后client和server协商出来假设是63,那么你发送60字节数据(ATT_payload),L2CAP会将它拆成3包(拆包的原因是因为BLE4.0链路层PDU的限制),最终从空中发出去的包长这样:

1)1字节前导码 + 4字节访问地址 + 2字节链路帧头(其中LLID = 10b,表示这是第一个连续包) + 4字节L2CAP帧头 + 3字节ATT帧头 + 20字节的ATT_payload + 3字节CRC
2)1字节前导码 + 4字节访问地址 + 2字节链路帧头(其中LLID = 01b,表示这是下一包连续包) + 27字节的ATT_payload + 3字节CRC
3)1字节前导码 + 4字节访问地址 + 2字节链路帧头(其中LLID = 01b,表示这是最后一个连续包) + 13字节的ATT_payload + 3字节CRC

分包的非第一包不需要L2CAP帧头和ATT帧头,增加了有效载荷。

3 如何提高BLE速率

1.使用2M PHY,需要双方都支持。
2.启用数据长度扩展特性(BLE4.2及以后支持)。
3.尽可能增大ATT_MTU,安卓支持最大512,IOS支持最大185。
4.减少连接间隔。详情如下:

连接间隔的更新决定权在主机,但从机可以发起申请。从机是发送conn_min_interval 、con_max_interval做为请求参数。所以作为从机,减少连接间隔,就是修改这两个参数。

修改方法1:
echo 6 > /sys/kernel/debug/bluetooth/hci0/conn_min_interval
echo 24 > /sys/kernel/debug/bluetooth/hci0/conn_min_interval
时间= 参数*1.25。
修改方法2:修改内核默认值
/linux/net/bluetooth/hci_core.c +3209

5.增大连接事件。

安卓和ios系统限制不一样。

6.修改读写方式,用write cmd代替write request,用notify代替indication。

7.最后检查实际空包中的连接事件与连接间隔。

展示一个空包,连接间隔15ms,交互包几乎占满。

Android开发 提升蓝牙传输速率 如何提升蓝牙传输速度_数据_04

4 理论最大速率的计算

假设采用write without response 、未启动加密(不包含MIC字段)

Android开发 提升蓝牙传输速率 如何提升蓝牙传输速度_Android开发 提升蓝牙传输速率_05


1.计算一个完整交互数据包的时间:

Packet_time = 传输空包的时间 + IFS + 传输实际数据包的时间 + IFS。
其中传输空包时间 = 空包大小(前导码 + 访问地址 + LL 报头 + CRC) / 原始数据速率 = 10*8字节/1Mbps = 80us
传输实际数据包的时间(ble4.0/4.1) =  1+4+2+4+23+3字节 / 1Mbps = 296us
传输实际数据包的时间(ble4.2) =  1+4+2+4+247+3字节 / 1Mbps = 2088us

2.计算应用数据最大速率:

Ble4.1 V= 有效数据/传输时间 =  (27*8)bits / (80+150+296+150)us = 312kbps = 39KB/s
Ble4.2 V= 有效数据/传输时间 =  (244*8)bits / (80+150+2088+150)us = 772kbps = 96KB/s
Ble5(2M phy) V= 有效数据/传输时间 =  (244*8)bits / (44+150+1048+150)us = 1369kbps = 171KB/s