提高BLE传输速度的方法

BLE(Bluetooh Low Energy)蓝牙低能耗本身是为了尽可能的节省电池电量,因此采样间歇式的收发机制,每次传输的数据量非常小,对于ATT来说,典型的是20字节,虽然后续版本的数据量有所增加,但设备厂商有不同的实现方式,设备具体支持多长的数据发送,还是需要应用层做兼容适配,这无疑增加了开发的工作量。本文主要探讨的是如何提高BLE 4.0版本下的数据传输率。
通常情况下,BLE传输数据量非常小, 有时候几百毫秒、甚至几秒十几秒才会发送一次用户数据,例如实时温度监控,智能穿戴设备的心率,计步上传等,有时候有需要实时大量的传送,例如设备固件的空中升级(OTA)、实时心电图,脉搏图等。 这就要求BLE设备提供在不同的应用场景下使用不同速率模式的能力,幸运的是,BLE早已考虑了这一点。规范里面提供了完善的机制来动态调整BLE主从设备的速率模式,其中一下几个参数最为重要,称为连接参数(connection params)
Interval Min
Interval Max
Latency
Timeout
下面以ble sniffer工具监听到的主从设备间更新连接参数的实际交互来说明这个过程。
以从机(穿戴设备)为准,在需要传输大量数据的时候,可以向主机发起调节连接参数的请求包,请求包中携带从机想要的连接参数信息:
在这里插入图片描述
这是一个L2CAP的数据包,方向为S->M表示从机发送到主机,SIG_Connection_Param_Update_Req字段中可以看到,从机想要的连接参数范围是
IntervalMin=0x10 -->16x1.25ms=20ms
IntervalMax=0x14 -->20=20x1.25ms=25ms
slavelatency=0
timeoutmultiplier=0x14 -->20=20x10ms=200ms

接着主机收到从机的请求参数后,会根据自己的实际能力,决定是否同意从机的要求,若同意则主机会在从机给出的参数范围内选择一个适合自己的参数,同时发起更新连接参数:
在这里插入图片描述
可以看到,这个数据包是LL层的,主机已同意了更新,并设置
interval=0x18 --> 24x1.25=30ms
latency=0
timeout=0x14 --> 20*10ms=200ms

之后主机还在L2CAP层针对从机的SIG_Connection_Param_Update_Req更新请求做了一个回应,表明主机是否同意从机请求:
在这里插入图片描述
这里可以看到SIG_connection_Param_Update_Rsp字段result为0,为成功。

除了可以通过减少连接事件的间隔来提高速率之外,还有另外一种方式。 我们知道BLE的 characteristic有两种写入方式: writeWithResponse和writeWithoutResponse,顾名思义,一种是写入数据到从机需要等待从机回应后才可以进行下一次发送,一种则不需要。
writeWithResponse需要回应的写入:
在这里插入图片描述
writeWithoutResponse无需回应的写:
在这里插入图片描述
对比两种方式的协议解析可以看到,writeWithResponse方式在从机发送ATT_Write_Req后必须等待从机ATT_Write_Rsp回应时才能发送下一个数据包,这中间间隔了3个数据包(包含ATT_Write_Rsp),而writeWithoutResponse使用ATT_Write_Command,无需等待回应,可以持续发送,两次发送之间仅间隔了一个数据包,这无疑会提高了传输的速率。

本文谈了两种提高BLE发送数据的方式,通过实际抓包展示了这两种方式的实际数据交互流程。需要说明的时,主机端应用层writeWithoutResponse方式持续发送,可能会把主机的发送队列填满,从而导致应用层的数据没有完整的投递到发送队列,造成丢包。实际开发中ios系统就发现,连续写入超过64帧(每帧20字节)数据后,后续的数据帧就会丢失,可以推测ios的ble发送队列大小应该是1KB,因此主机端需要一定的机制来解决这个问题,另外,发送和接收端的上层应用层需要根据业务逻辑,对ble协议栈提交上来的数据做一定的完整性校验。

以上为实际开发过程中的一点体会和记录,虽然部分术语可能表述不正确,但希望对大家有点参考启示作用。

猜你喜欢

转载自blog.csdn.net/wenshifang/article/details/109080742