文章从以下几个问题着手分析蓝牙5的速率:
- BLE的实际吞吐量是多少?
- 蓝牙5的新2M PHY用于数据传输?
- 影响/确定数据吞吐量的因素有哪些?
- 如何计算应用程序中的数据吞吐量?
- 如何最大化数据吞吐量?
实际吞吐量
蓝牙5定义的 LE 2M PHY以及蓝牙4.x协议 LE 1M PHY都称为未编码PHY,因为它们每位数据使用1个符号表示(与使用S=2或S=8的新LE编码PHY相比)。
我们需要明白各大芯片厂商数据手册宣传的速度(1 Mbps和新的2 Mbps)仅仅只是理论值(空中速率),并且在应用程序中吞吐量会被削减。原因有多种,我们将在下面一一介绍。
蓝牙5“2x速度”需要硬件支持,因此老的设备/芯片/模块将不支持蓝牙5 2M PHY(市面已经有手机支持蓝牙5 2M PHY)。要注意,为了实现更高吞吐量,需要两个BLE设备相互都支持LE 2M PHY。
此外,当使用更高速度的PHY时,实际上功耗可以做的更低(传输相同数量的数据,时间短功耗低)。这是因为减少了芯片工作时间而又没有增加发射功率。反过来这样做改善了与2.4 GHz频谱内的其他无线技术的共存(也是由于减少了无线电工作时间,减少2,4G带宽的占用)。
为什么不可能达到BLE的理论速度?
1 Mbps(LE 1M PHY),2 Mbps(LE 2M PHY),125 kbps和500 kbps(均使用LE编码PHY,S = 8和S = 2)的数据速率是无线电在空中的速率传输数据,但由于以下原因,应用程序吞吐量是达不到该理论值:
- 蓝牙规范限制每个连接间隔的数据包数量
- 数据包之间的帧间间隔(IFS)延迟(150 us)
- 即使没有可用于传输的数据,也需要从设备发送空数据包
- 数据包开销 - 并非数据包中的所有字节都用于有效负载
我们感兴趣的部分(真正定义应用程序数据的部分)是ATT Payload。 从图中可以看出,蓝牙低功耗中的每一层都使用了许多额外开销字节。
在4.0和4.1中,最大ATT有效载荷为20个字节。
在4.2和5.0中,称为数据长度扩展(DLE)的新功能允许ATT有效载荷最多可容纳244个字节的数据。
蓝牙5速率:使用新的2M PHY实现2倍速
首先了解下蓝牙5中使用新LE 2M PHY的局限性:
- 不能用于主要广播信道(37,38,39)。
- 可用于与数据包在同一通道上发送的辅助“辅助数据包”(37个通道:0-36)。
蓝牙5规格书说明,LE 1M PHY是强制性的,而LE 2M PHY是可选的,因此,并非所有声称支持蓝牙5的芯片都必须能够处理更高的吞吐量。
LE 2M PHY上可以发生从端广播模式和主端扫描模式,然后使用LE 2M PHY在第二广告信道上进行连接。
用户交互数据从一个设备传输到另一个设备是发生在两个设备的连接阶段。连接的设备可以通过更新PHY来协商使用不同PHY。它可以在建立连接后由从设备或主设备发起,但主设备最终将决定哪个PHY(基于从设备的请求和主设备支持的PHY)。影响BLE应用程序的数据吞吐量因素:
- 使用的PHY(LE 1M vs. LE 2M与LE编码(S = 2或S = 8))
- 连接间隔
- 每个连接间隔的最大数据包数
- ATT最大传输单元(ATT MTU)
- 数据长度扩展(DLE)
- 操作类型:写入响应与写入无响应,指示与通知
- 帧间间隔(IFS):后续数据包之间的时间间隔(150 us)
- 传输空包
- 数据包开销 - 并非数据包中的所有字节都用于应用程序有效负载
根据这9点,我们一点一点详细地讨论。
PHY
蓝牙5中基本上有三种PHY:原始的1 Mbps PHY,新的2 Mbps和编码的PHY(S = 2或S = 8)。所使用的PHY将直接影响您可以实现的最大数据吞吐量,因为它确定了通过无线方式发送数据包的实际原始数据速率。
每个连接事件的连接间隔和最大数据包
连接间隔有效地确定在一个连接事件期间可以发送多少数据包。值越高,在一个连接事件中可以发送的数据包越多(某些设备达到某个限制)。
BLE连接间隔和事件
每个连接事件的数据包数量取决于设备和BLE堆栈,因此它受到限制,并且在特定设备上的设备和堆栈版本之间有所不同。此值还取决于设备的操作,因此无线电可能必须处理其他事件,并且每个连接事件发送的数据包数量可能达不到堆栈允许的最大值。例如,iOS和Android之间的数量不同,也会根据设备上运行的操作系统版本而有所不同。
数据长度扩展(DLE)
此功能允许数据包大小保持更大的有效负载(最多251个字节,而禁用时为27个字节)。此功能是在蓝牙规范4.2版中引入的。
ATT最大传输单元(ATT MTU)
ATT MTU确定发送器和接收器可以处理的最大数据量以及它们可以保存在缓冲器中的数据量。
MTU值影响开销数据量(特别是3个字节的ATT头)。允许的最小ATT MTU是27个字节。这允许最多20个字节的ATT有效载荷(3个字节用于ATT报头,4个字节用于L2CAP报头)。
对于MTU值有多高,每个规范没有限制,但使用中的特定堆栈可能有其自身的局限性。例如,如果启用DLE,则最多可以传输251 - 4 = 247个字节(扣除L2CAP标头大小后)。在考虑ATT报头(3个字节)之后,我们留下了244个字节用于实际的ATT有效载荷数据。如果MTU至少为247字节,则MTU将适合一个单独的数据包。如果MTU大于247字节,则MTU将跨越多个分组,导致吞吐量下降(由于分组开销和分组之间的定时)。
有效MTU由客户端和服务器支持的ATT MTU的最小值确定。例如,如果客户端支持100字节的ATT MTU并且服务器响应它支持150字节的ATT MTU,则客户端将决定用于从其上进行连接的ATT MTU是100字节。
操作类型:写入响应与写入无响应,指示与通知
如果需要高吞吐量,那么我们可以使用Write without response或Notifications将数据从客户端传输到服务器以及从服务器传输到客户端。这些操作不需要其他设备确认收到数据并在下一个数据块发送之前做出响应。
帧间间隔(IFS):连续数据包之间的时间延迟(150 us)
蓝牙规范:传输空包
如果接收数据的设备没有要发回的数据,则仍需要按照蓝牙规范发送空数据包。
数据包开销
正如我们在数据包格式图中看到的那样,数据包包含一些不计入应用程序数据(ATT数据)的开销数据。基本上,这些字节将消耗部分传输数据速率,而不考虑作为应用程序数据的一部分发送的任何字节。
计算应用程序数据吞吐量
正如我们之前提到的,有如下些因数会影响数据吞吐量:
- 使用蓝牙版本和PHY
- DLE:数据长度扩展 - 启用与否
- ATT MTU值
- 连接间隔
- 每个连接事件的最大数据包数
- 操作(写入响应与写入没有响应,以及通知与指示)
- 帧间间隔(IFS):150微秒
蓝牙版本和PHY确定原始数据传输速率。例如,如果我们使用蓝牙版本4.2和LE 1M PHY,则传输速率为1 Mbps。另一方面,如果我们使用蓝牙5 S = 8的 LE编码PHY,则数据速率降至125 kbps。
DLE,ATT MTU,连接间隔,每个连接间隔的最大数据包数,操作和IFS都是用于实际数据传输时间。
数据包格式在传输的数据量是实际应用程序数据方面起着重要作用。 LE 1M PHY和LE 2M PHY都具有类似的数据包格式。 LE编码PHY具有明显不同的数据包格式,因此我们将分别查看这两种情况:LE 1M PHY和LE 2M PHY计算。
参考LE未编码PHY的数据包格式:
针对不同PHY,数据开销略有不同。 对于1M PHY,前导码是1字节,而对于2M PHY,前导码是2字节。 MIC字段是可选字段,仅用于加密连接。 为简单起见,我们只考虑未加密的连接 - 对于加密的情况,它只是增加了4个字节的开销。
对于LE编码PHY,数据包格式如下所示(来自蓝牙5.0规范第6卷,第B部分,第2.2节):
计算吞吐量的步骤(以Mbps为单位):
为简单起见,我们做假设如下:
- 未启用加密(数据包中不包含MIC字段)。
- 我们感兴趣的是单方向的吞吐量(例如Master to Slave),所以我们假设另一个方向只传输空数据包。
- 写入时,对方无需响应(No Ack)。
步骤:
- 确定正在使用的PHY并记下原始数据传输速率
例如: 对于1M PHY - > 1 Mbps,对于编码PHY和S = 8 - > 125 kbps
-
确定从接收器发送一个数据包和空包的时间。
可以发送一个数据包的时间包括以下内容:
Data_Packet_Time =发送空包的时间+ IFS +发送实际数据包+ IFS的时间
空包传输时间可以如下计算:
传输空包的时间=空包大小/原始数据速率
空包将包含以下字段:前导 + 访问地址(access address)+ LL头+ CRC。
对于1M PHY,前导将为1字节,因此空包的总大小= 1 + 4 + 2 + 3字节= 10字节= 80位。
对于2M PHY,空数据包的大小将为88位,因为Premable是2个字节而不是1个字节)。
基于此,传输空1M PHY数据包的时间将是:
传输空数据包的时间=空数据包大小/原始数据速率= 80位/ 1兆位/秒= 80微秒
数据包将包含数据包格式图中列出的所有字段,但MIC字段除外(加密禁用)。
传输数据包的时间=数据包size / raw data rate
如果我们启用了DLE并且ATT MTU等于一个数据包中允许的最大字节数:247个字节,那么我们可以将数据包大小计算为:
数据包size= 1 + 4 + 2 + 4 + 247 + 3字节= 265字节= 265 * 8位= 2088 bit
发送数据包的时间= 2088位/ 1 Mbps = 2,088us
Data_Packet_Time =发送空包的时间+ IFS +发送实际数据包的时间+ IFS = 80 + 2 * 150 + 2088 = 2,468us
在2M PHY的情况下,它将是:
Data_Packet_Time =发送空包的时间+ IFS +发送实际数据包的时间+ IFS = 88/2 + 2 * 150 +(2 + 4 + 2 + 4 + 247 + 3)* 8/2 = 1,392us
当启用DLE并且ATT MTU设置为小于247时,会产生更多开销(因为现在大于ATT MTU的数据被分成更多数据包)。例如,假设我们将ATT MTU设置为158,那么为了传输244个字节的应用程序数据,我们需要两个数据包而不是一个,导致吞吐量因字节开销增加而增加而增加数据包之间的IFS。
在另一种情况下,我们可以禁用DLE(有效负载大小最多27个字节)和ATT MTU大于27个字节。这也将导致需要为相同数量的数据发送更多数据包,从而导致吞吐量下降。
注意:
用于计算上面使用的数据和空数据包大小的方法可以用于计算LE编码PHY。
一个连接间隔期间可以传输多少数据包
前一篇文章讲过,这种计算并不总是纯粹的数学计算,需要考虑使用的堆栈和设备的限制。在蓝牙芯片供应商的SDK中,通常在其文档中会列出最大值。 iOS和Android的最大值随操作系统版本而变化,所以要弄清楚并不容易。
一旦计算出最大值,就可以计算出适合所选连接间隔的最大理论数据包数。例如,如果我们的连接间隔为7.5毫秒(规范允许的最低值),则对于上面的示例(使用1M PHY,启用DLE):
每个连接间隔的最大数据包数= [连接间隔/ Data_Packet_Time]
其中[] 表示舍入到最大整数(整数)。
每个连接间隔的最大数据包数= [7.5 * 1,000微秒/ 2,468微秒] = 3个数据包
通常,这个数字是不现实的,因为在连续的连接事件上发送的数据包之间存在时间延迟。因此,对于我们的示例,我们将使用2个数据包而不是3个数据包。
一旦我们计算出每个连接间隔可以传输的最大数据包数,我们就可以计算出数据吞吐量:
数据吞吐量 = 每个连接间隔的数据/连接间隔 = 每个连接间隔的数据包数量*每个数据包/连接间隔的数据大小
= 2 * 244 * 8位/7.5毫秒= 520,533位/秒〜= 508kbps
大家会认为,连接间隔越小,速率肯定更高,实际并不是这样的。
下面就根据真实测试数据和计算理论值一一对比。总结:
路由器,蓝牙,手机wifi等2.4G的设备干扰,测试设备主从之间的距离,设备之间存在障碍等因数都会影响测试结果。
上面列出的测试值和理论值,可能实际环境中的测量数据吞吐量不一致。
干扰和传输/接收错误会影响数据吞吐量(重试,数据丢失和连接事件关闭会导致吞吐量降低)。
但本文详细分析了所有和速率相关的因素,在实际使用中,大家可以自由DIY。
网友评论