Nordic芯片如何达到最快的蓝牙传输速率

您所在的位置:网站首页 传输速度class10是最快得么 Nordic芯片如何达到最快的蓝牙传输速率

Nordic芯片如何达到最快的蓝牙传输速率

2023-12-16 03:13| 来源: 网络整理| 查看: 265

简介

目前BLE已经发布到BLE5.2的标准,而蓝牙的传输速率,在BLE4.2和BLE5.0版本上分别进行了提升,这里介绍下使用Noridc芯片时,如何进行配置,以达到最快的传输速度(只讨论1主对1从的情况)。

基础概念介绍

这里对一些后面用到的名词做一下简单介绍,如果要详细了解,可以自行进行查找。

在BLE中,作为Client端,可以通过write command和write request方式进行发送数据,参考蓝牙规范Vol3.Part F.3.4.5章节。 write command : client向server发送命令,不需要server给应答。 write request : clien向server发送请求,需要server给出ack。

作为server端,可以通过Notification和indication方式发送数据给client端,参考蓝牙规范Vol3.Part F.3.4.7章节。 Notification:server向client发送通知,不需要client应答。 Indication : server向client发送通知,需要client应答。

ATT_MTU : MAXIMUM TRANSMISSION UNIT,即在一个传输单元中的最大有效数据传输量,mtu的格式为1字节op_code,2字节attr handle,因此实际一帧传输的用户数据为ATT_MTU-3。在BLE4.0中,只支持23的ATT_MTU,在BLE4.2以后,ATT_MTU最大可以是247字节。

DLE: dat length extension,一般建议设置为ATT_MTU+4,如果低于ATT_MTU,ATT data会被分包,这里记得就行,后面会单独开一个章节介绍一下。

CLE :connection event length extension,链接事件长度扩展,在BLE4.0中,单个连接间隔,最多只能发送4(IOS)或者6(Android)个数据包,当打开CLE功能时,协议栈会判断链接间隔剩下的时间是否还支持发送数据包,如果还有时间,那么会继续进行数据发送,而不是受限于6个包。

connection interval :链接间隔,主从机建立连接以后,每隔多久交互一次数据,IOS要求连接间隔最小时15ms,最大最小之间的时间差值最低15ms,因此IOS支持的最快连接间隔最小最大分别是15ms-30ms,安卓端最低7.5ms。

官方理论值

Nordic官方公布的协议栈理论速度如下,这里只讨论最快速度,所以只看没有ack的Notification和Indication方式参考协议栈手册BLE data throughput章节:

nRF51

nRF51不支持ATT_MTU扩展,也不支持DLE,CLE和LE 2M PHY,因此,使用最快的7.5ms的连接间隔,23字节的ATT_MTU,BW Config配置为HIGH时,Notification和write command方式速率为149.2kbps,Indication和write request方式速率为10.6kbps。 在这里插入图片描述

nRF52

nRF52系列支持上面所有的特性。 在ATT_MTU=23,其他特性都不打开的情况下,也就是BLE4.0的标准特性下,传输速率如下图所示:

对比上面的51系列,可以看到,同样的LE 1M PHY条件下,52的速率为192kbps,速度提高了53kbps左右,而LE 2M PHY情况下,速率为256kbps。

在ATT_MTU=158,其他特性都不打开的情况下,传输速率如下图所示: 在这里插入图片描述

可以看到,在2M PHY的情况下,速率为330kbps。

在ATT_MTU = 247,DLE=251,CLE = conn interval情况下,传输速率如下: 在这里插入图片描述

在打开CLE的情况下,传输速率最快达到1376kbps,这个就是目前我们所能达到的最快的速率。

可以看到,影响蓝牙传输速率的因素有:

连接间隔ATT_MTU SIZEDLELE PHYCLE 代码实例测试

以下代码测试均以Nordic SDK中的ble_app_uart为基础,手机端使用安卓一加6进行测试,手机支持上面提到的所有特性。:

nRF51

目前nordic支持51的最后一个版本sdk为SDK12.3,以该版本sdk为例进行测试,开发环境为keil。 由于nRF51在传输速率方面只支持BLE4.0,所以我们需要配置的参数只有连接间隔和BW Config选项。

对于链接间隔,理论上是越小越好,但是IOS要求最低是15ms-30ms,因此,使用这个范围,可以达到最快的传输速度,但是考虑到手机兼容性,可以适当的将这个最大值调高一点。

还有就是协议栈初始化时,配置BW Config为high。

ble_common_opt_conn_bw_t opt_conn_bw; opt_conn_bw.role = role; opt_conn_bw.conn_bw.conn_bw_tx = BLE_CONN_BW_HIGH; opt_conn_bw.conn_bw.conn_bw_rx = BLE_CONN_BW_HIGH; return sd_ble_opt_set(BLE_COMMON_OPT_CONN_BW, (ble_opt_t const *)&opt_conn_bw);

role的角色定义如下,根据自己需要配置。

/**@defgroup BLE_GAP_ROLES GAP Roles * @note Not explicitly used in peripheral API, but will be relevant for central API. * @{ */ #define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ #define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ #define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */

51的配置部分比较少,需要注意的是,在发送数据的时候,只要api的返回值不是 NRF_ERROR_RESOURCES或者在更早的sdk中,应该是NRF_ERROR_NO_TX_BUFFER,就连续调用发送的api进行发送数据。 如果发生了上面的error,那么就等触发一个tx_complete事件,再继续发送。

nRF52系列

github测试demo:https://github.com/faithlm/ble_app_uart_throughout_test

目前最新版本SDK为sdk17.02,以该版本sdk进行测试,以该版本sdk为例进行测试,开发环境为ses。 从上面协议栈参数配置可知,如果要达到最快的速率,需要配置如下参数:

增大ATT_MTU

目前协议栈支持的最大 att_mtu 为247,如果要修改,可以更改sdk_config中的如下选项:

// NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. #ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247 #endif 增大DLE

目前版本协议栈支持最大的DLE为 251,可以通过sdk_config.h 的如下选项进行配置:

// Requested BLE GAP data length to be negotiated. #ifndef NRF_SDH_BLE_GAP_DATA_LENGTH #define NRF_SDH_BLE_GAP_DATA_LENGTH 251 #endif 打开CLE

连接事件长度扩展,可以通过下面接口进行配置,配置放在协议栈初始化后面:

//status 为true时,打开CLE void conn_evt_len_ext_set(bool status) { ret_code_t err_code; ble_opt_t opt; memset(&opt, 0x00, sizeof(opt)); opt.common_opt.conn_evt_ext.enable = status ? 1 : 0; err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt); APP_ERROR_CHECK(err_code); }

这里还有一个参数需要注意,NRF_SDH_BLE_GAP_EVENT_LENGTH,这个定义了连接事件的长度,单位是1.25ms,在sdk_config.h中配置,一般情况下,这个值可以等于连接间隔:

// NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. // The time set aside for this connection on every connection interval in 1.25 ms units. #ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH #define NRF_SDH_BLE_GAP_EVENT_LENGTH 400 #endif 使用LE 2M PHY:

目前支持3中LE PHY,分别是LE 1M PHY,LE 2M PHY,LE CODED PHY,其中LE 2M PHY用于高速率,,而理论距离是LE 1M PHY的一半,而LE CODED PHY用于长距离模式,LE 1M PHY兼顾了距离和速率,可以根据自己实际需要进行选择,如果对传输距离有要求,需要谨慎选择。 LE PHY 可以通过调用sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)接口发起更新,一般在peripheral端,收到ble_evt_connected事件的时候进行请求更新。如下所示,即可配置为只支持2M 的PHY:

static test_params_t m_test_params = { .phys.tx_phys = BLE_GAP_PHY_2MBPS, .phys.rx_phys = BLE_GAP_PHY_2MBPS, }; static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) { uint32_t err_code; ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: //这里只写phy更新部分,其他的省略 err_code = sd_ble_gap_phy_update(p_gap_evt->conn_handle, &m_test_params.phys); APP_ERROR_CHECK(err_code); break; } } 调整连接间隔

由于启用了CLE功能,所以这里不需要根据nRF51的方式,使用最小的连接间隔,调整一个比较大的就可以,注意,需要保持NRF_SDH_BLE_GAP_EVENT_LENGTH大于等于连接间隔,协议栈给出的参考值是50ms或者400ms,对应的速率分别是1328kbps和1376kbps。

#define CONN_INTERVAL_MIN (uint16_t)(MSEC_TO_UNITS(50, UNIT_1_25_MS)) /**< Minimum acceptable connection interval, in units of 1.25 ms. */ #define CONN_INTERVAL_MAX (uint16_t)(MSEC_TO_UNITS(60, UNIT_1_25_MS)) /**< Maximum acceptable connection interval, in units of 1.25 ms. */ 增大协议栈发送buff

在ram空间有剩余的情况下,可以给协议栈配置更大的queue大小,增大缓存,默认值是1,根据实际情况配置。 下面的给协议栈配置了长度为7的队列缓冲区。

memset(&ble_cfg, 0, sizeof(ble_cfg)); ble_cfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG; ble_cfg.conn_cfg.params.gattc_conn_cfg.write_cmd_tx_queue_size = 7; ble_cfg.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = 7; err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTC, &ble_cfg, ram_start);

注意,经过上面的修改以后,在协议栈初始化时,会报NO_MEM的错误,,如下图所示,这个时候log会提示需要将ram修改为多大,根据需要进行调整即可: 在这里插入图片描述

经过上面修改,即可达到最大的传输速率,理论值是1376.2 kbps

github上的demo,增加了数据发送及时间记录,可以进行验证,测试结果如下图,8s时间,发送1220*1000 Byte数据,相当于传输速率为1220kbps,已经接近理论极限值。

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3