当前位置: 首页 > news >正文

BLE 蓝牙连接参数详解

学习一下蓝牙连接参数相关知识      ...... 矜辰所致

前言

在我们学习蓝牙示例的时候,只要是从机示例,在最初初始化的时候都会设置两个参数 :GAPROLE_MIN_CONN_INTERVALGAPROLE_MAX_CONN_INTERVAL,最小连接间隔和最大连接间隔,它们属于蓝牙的连接参数,那么它们在蓝牙协议中究竟有何意义,与他们相关联的参数还有哪些?本文我们就来了解一下 Ble 蓝牙连接参数相关知识。

沁恒微 RISC-V 蓝牙专栏目录:【导航】沁恒微 RISC-V 蓝牙 入门教程目录 【快速跳转】
❤️
蓝牙篇系列相关博文:
CH585 蓝牙 示例工程 Central 全解析
.
我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

  • 前言
  • 一、 基础介绍
    • 1.1 基本概念
      • 1.1.1 连接间隔
      • 1.1.2 从设备延迟
      • 1.1.3 监督超时
    • 1.2 连接参数更新
    • 1.3 关于保活
    • 1.4 连接间隔的实际时间
      • 1.4.1 连接间隔的确定
      • 1.4.1 连接间隔时间是多少?
      • 1.4.2 为什么 Ble 协议需要范围间隔
  • 二、 CH585 示例体现
    • 2.1 初始化
    • 2.2 参数更新
      • 2.2.1 从机
      • 2.2.2 主机
    • 2.3 更新结果查看
    • 2.4 更新流程
  • 结语

一、 基础介绍

连接参数,连接连接,顾名思义,只有 Ble 蓝牙建立了连接才会生效的参数,用于控制从机(Peripheral)与主机(Central)之间的通信频率。

1.1 基本概念

在沁恒微官方 EVT 中示例 BLE 文件夹下面有一份 《沁恒低功耗蓝牙软件开发参考手册》,在低功耗蓝牙协议栈部分章节对连接参数有描述。我们这里也过一遍基本概念。

1.1.1 连接间隔

连接间隔(Connection Interval) 是指主机与从机之间每次通信的时间间隔。

低功耗蓝牙采用的是跳频方案,设备在特定的时间在特定的通道上发送和接收数据。两个设备的一次数据发送与接收成为一个连接事件。连接间隔则为两个连接事件之间的时间,

时间单位: 1.25ms (比如 100 → 125ms )

连接间隔的范围: 7.5ms~4s。

不同的应用可能会需要不同的连接间隔,连接间隔的影响:

连接间隔小连接间隔大
通信频繁,响应快通信稀疏,响应慢
功耗高功耗低
适合高吞吐量应用(如OTA、音频)适合低功耗应用(如传感器定时上报)

1.1.2 从设备延迟

从设备延迟(SlaveLatency)是指 从设备可以跳过的最大事件数(就是可以跳过几次间隔不回响应)。
此参数可以让从机跳过部分连接事件。如果设备没有数据需要用发送,那么从机延时可以跳过连接事件并在连接事件期间停止射频,从而降低功耗。

从设备延迟范围: 0~499 ,但需保证有效连接间隔小于16s。

比如文档示例如下:
在这里插入图片描述

1.1.3 监督超时

监督超时(SupervisionTime-out) 两个有效连接事件间的最大时间。超过这个时间没有收到包,则认为连接断开,设备退回未连接状态。

时间单位: 10 ms

监督超时的范围: 10(100ms)~3200(32s)。

超时时间必须大于有效连接间隔。

必须满足:

timeout × 10 ms > (1 + SlaveLatency) × ConnectionInterval × 1.25 ms

1.2 连接参数更新

在主机和从机连接以后,是可以更新上面的几个连接参数的,但是都需要协商,在官方文档中又说到 “在一些应用中,从机可能需要在连接期间根据应用程序更改连接参数。从机可以将连接参数更新请求发送至主机以更新连接参数。”

官方只说到,从机更改参数,但是主机也可以更改连接参数。

在主机示例工程中,使用下面函数更新参数:

/*** @brief   Update the link connection parameters.** @param   connHandle - connection handle* @param   connIntervalMin - minimum connection interval in 1.25ms units* @param   connIntervalMax - maximum connection interval in 1.25ms units* @param   connLatency - number of LL latency connection events* @param   connTimeout - connection timeout in 10ms units** @return  SUCCESS: Connection update started started.<BR>*          bleIncorrectMode: No connection to update.<BR>*/
extern bStatus_t GAPRole_UpdateLink( uint16_t connHandle, uint16_t connIntervalMin,uint16_t connIntervalMax, uint16_t connLatency, uint16_t connTimeout );

在从机示例工程中,使用下面函数更新参数:

/*** @brief   Update the parameters of an existing connection** @param   connHandle - the connection Handle* @param   connIntervalMin - minimum connection interval in 1.25ms units* @param   connIntervalMax - maximum connection interval in 1.25ms units* @param   latency - the new slave latency* @param   connTimeout - the new timeout value* @param   taskId - taskID will recv L2CAP_SIGNAL_EVENT message** @return  SUCCESS, bleNotConnected or bleInvalidRange*/
extern bStatus_t GAPRole_PeripheralConnParamUpdateReq( uint16_t connHandle, uint16_t connIntervalMin,uint16_t connIntervalMax, uint16_t latency, uint16_t connTimeout, uint8_t taskId );

更新包含以下参数:最小连接间隔、最大连接间隔、从设备延迟、监督超时

维度PeripheralConnParamUpdateReqUpdateLink
谁调用Peripheral 角色Central 角色
底层行为请求 → 等主机 Accept/Rsp → 再生效UPDATE_IND → 立即生效(或对端拒)
协商阶段✅ 有,从机向主机协商❌ 无,直接通知
从机能否拒绝✅ 主机可拒,请求不生效✅ 底层自动拒(若超范围),不断线
返回值SUCCESS / bleNotConnected / bleInvalidRangeSUCCESS /bleIncorrectMode
结果通知通过 peripheralParamUpdateCB() 回调Central 无回调;通过事件GAP_LINK_PARAM_UPDATE_EVENT返回

1.3 关于保活

建立连接以后, 保活永远是主机先发起,从机回应! 不管有没有从设备延迟,主机永远按每个简介间隔询问。

如果设定了从设备延迟,从机可以在期间不回应,但是主机必须按时出现询问。

1.4 连接间隔的实际时间

上面虽然我们知道了什么事连接间隔,但是在我们示例中,都需要定义两个时间:最小连接间隔和最大连接间隔,他是一个范围,那么连接上以后,他到低是多少时间呢?

1.4.1 连接间隔的确定

连接间隔是如何确定的,我们能够很直观的看到,从机设备都是需要给定最小最大范围的, 主机会在自己策略允许的前提下,挑一个落在从机区间里的值。

虽然是不可控的,但是也不是随机的,主机内部有自己的算法+用户体验策略,但它必须先把你给的区间扫一遍,主机会根据自己的性能定位在区间内挑一个 ≥ min 且 ≤ max 的 1.25ms 整数倍,且固定不变直到下一次更新,考虑的方面比如:

  • 自己系统性能档位(iOS ≥15 ms、音频 20 ms、鼠标 30 ms …)
  • 多从机排班(避开已有设备的跳频点)
  • 功耗策略(前台 App 要快、后台要省)
  • Wi-Fi 共存(避开 100/200 ms 倍数)

连接间隔的确定 是主机根据自身策略做的确定性选择,只是从机无法预知具体会选哪一点。

如果想确定一个准确的时间间隔, 从机可以把最小连接间隔和最大连接间隔设定为相同的时间,这样就把连接间隔给固定下来。但是呢主机有可能拒绝的,这个要看主机自己的配置和状态,比如自己多设备从图,占用了某些固定设备的间隔等等。

1.4.1 连接间隔时间是多少?

上面说了实际的连接间隔,会在从机和主机建立连接以后由主机确定,但是这个时间是多少,主机并不会主动告诉从机,但是在示例中,从机可以通过自己注册的回调函数peripheralParamUpdateCB查看:

static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,uint16_t connSlaveLatency, uint16_t connTimeout)
{if(connHandle == peripheralConnList.connHandle){peripheralConnList.connInterval = connInterval;peripheralConnList.connSlaveLatency = connSlaveLatency;peripheralConnList.connTimeout = connTimeout;PRINT("Update %x - Int %x \n", connHandle, connInterval);}else{PRINT("ERR..\n");}
}

1.4.2 为什么 Ble 协议需要范围间隔

为什么连接间隔不能是一个固定值,反正从机确定,主机按照固定值连接就好了。

其实上面也说到了,如果主机连接多个从机,大家有冲突的话就会有设备连接不上了,而且这样做是为了在 “用户体验”、“射频共存” 和 “功耗” 三者之间留动态调节空间。

比如一些常用的设备:

设备从机声明区间手机实际分配
耳机6 – 1210 ms
鼠标8 – 5030 ms
温湿度计100 – 20001 s
手环40 – 200200 ms

手机把四段区间做 TDM(时分复用),让不同设备错开跳频点,避免撞包。

另外,苹果/安卓设备有 “硬门槛” :

iOS ≥ 15 ms(HID 除外)
某些 Android 旧机 ≤ 24 ms 会触发 Wi-Fi 共存模块报警
如果从机写死 10 ms,iPhone 直接砍掉 15 ms,
此时协议栈需要再挑一个“离你最近且我合法”的值;
有区间就能 “向上取整”,没区间就只能连不上。

二、 CH585 示例体现

下面来结合实际代码,看看上面的这些参数在程序中用到的地方:

2.1 初始化

在从机例程 peripheral 中,有4个宏定义,分别对应了最小连接间隔,最大连接间隔,从设备延迟,监督超时:

// Minimum connection interval (units of 1.25ms, 6=7.5ms)
//最小连接间隔
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL    6// Maximum connection interval (units of 1.25ms, 100=125ms)
//最大连接间隔
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL    100// Slave latency to use parameter update
//从设备延迟,默认不延迟
#define DEFAULT_DESIRED_SLAVE_LATENCY        0// Supervision timeout value (units of 10ms, 100=1s)
//监督超时   1S 超时
#define DEFAULT_DESIRED_CONN_TIMEOUT         100

但是初始化的时候,从机只能确实最小连接间隔和最大连接间隔,和从设备延迟(默认为0)。

连接建立前从机无法把监督超时直接塞进广播数据(广播里没有 AD Type 能放 SupervisionTime-out),

在这里插入图片描述

上面没有设置的从机设备延迟,默认为0 ,如果从机不设置最小最大值就使用默认值,官方默认值如下:

//!< Minimum Connection Interval to allow (n * 1.25ms).  
//Range: 7.5 msec to 4 seconds (0x0006 to 0x0C80). 
//Read/Write. Size is uint16_t.
//Default is 7.5 milliseconds (0x0006).
#define GAPROLE_MIN_CONN_INTERVAL               0x311
//!< Maximum Connection Interval to allow (n * 1.25ms).  
//Range: 7.5 msec to 4 seconds (0x0006 to 0x0C80). 
//Read/Write. Size is uint16_t. 
//Default is 4 seconds (0x0C80). 
#define GAPROLE_MAX_CONN_INTERVAL               0x312  

主机初始化会有监督超时参数:

在这里插入图片描述

监督超时它只在连接建立时由主机设置,从机只能接受或拒连,事后才能通过更新请求去改。

2.2 参数更新

对于我们主机和从机,都可以发起参数更新,从机是协商请求,主机类似于下达通知。

2.2.1 从机

从机使用GAPRole_PeripheralConnParamUpdateReq 更新连接参数,在示例中,步骤如下:

//启动任务事件
tmos_start_task(Peripheral_TaskID, SBP_PARAM_UPDATE_EVT, SBP_PARAM_UPDATE_DELAY);//执行事件
if(events & SBP_PARAM_UPDATE_EVT){// Send connect param update request// When the current connection parameters already meet the requirements for update, return 0x18(InvalidRange)GAPRole_PeripheralConnParamUpdateReq(peripheralConnList.connHandle,DEFAULT_DESIRED_MIN_CONN_INTERVAL,DEFAULT_DESIRED_MAX_CONN_INTERVAL,DEFAULT_DESIRED_SLAVE_LATENCY,DEFAULT_DESIRED_CONN_TIMEOUT,Peripheral_TaskID);return (events ^ SBP_PARAM_UPDATE_EVT);}

2.2.2 主机

主机使用GAPRole_UpdateLink 更新连接参数,在示例中,步骤如下:

//启动任务事件
tmos_start_task(centralTaskId, START_PARAM_UPDATE_EVT, DEFAULT_PARAM_UPDATE_DELAY);//执行事件
if(events & START_PARAM_UPDATE_EVT)
{// start connect parameter updateGAPRole_UpdateLink(centralConnHandle,DEFAULT_UPDATE_MIN_CONN_INTERVAL,DEFAULT_UPDATE_MAX_CONN_INTERVAL,DEFAULT_UPDATE_SLAVE_LATENCY,DEFAULT_UPDATE_CONN_TIMEOUT);return (events ^ START_PARAM_UPDATE_EVT);
}

2.3 更新结果查看

这里直接在最前面说清楚:

从机设备 连接参数更新成功是会触发系统注册的回调函数peripheralParamUpdateCB ,在回调函数中处理。

主机设备 连接参数更新成功是在任务事件里处理:GAP_LINK_PARAM_UPDATE_EVENT

角色接收方式所在文件事件/回调名
Peripheral回调函数peripheral_main.cperipheralParamUpdateCB()
Central任务事件central_main.cGAP_LINK_PARAM_UPDATE_EVENT

在 peripheral 角色 下,CH585 的官方库固定走回调指针,根本不会把 GAP_LINK_PARAM_UPDATE_EVENT 塞进任务队列,从机想拿结果必须注册回调函数。

主机为什么走任务事件不走回调函数呢?

因为中心设备要同时管理多条连接,如果每条连接都开一个回调指针,每一个都需要占用 RAM 空间,浪费RAM空间,而且后期操作的时候不方便管理。

这里额外说明一下,对于主机连接多个从机:

// 主机保存着 8 条连接的上下文,参数更新
for (i = 0; i < MAX_CONNECTIONS; i++) {if (centralConnList[i].state == GAPROLE_CONNECTED &&centralConnList[i].paramUpdateNeeded) {// 只更新这一条从机GAPRole_UpdateLink(centralConnList[i].connHandle,newMin, newMax, newLatency, newTimeout);centralConnList[i].paramUpdateNeeded = FALSE;}
}//结果
case GAP_LINK_PARAM_UPDATE_EVENT:p = (gapLinkUpdateEvent_t *)pMsg;// p->connHandle 告诉你“到底是哪条连接”PRINT("从机 %04X 新间隔 %d ms\n", p->connHandle, p->connInterval);break;

2.4 更新流程

上面我们知道了,主机和从机都有自己的更新成功接收的地方。

那么它们自己发出的更新请求,自己是否会触发回调或者事件呢?

其实这个是异步的,这个只要记住一点:不管参数更新请求是谁先发,只要通过协议栈的协商确定通过后,库就会通过事件/回调告诉应用层 “参数已换”

比如:

主机发送GAPRole_UpdateLink -> 从机接收到并且同意(协议栈自动完成) -> 同一连接事件末尾:主机进GAP_LINK_PARAM_UPDATE_EVENT 同时从机进 peripheralParamUpdateCB()

从机发送GAPRole_PeripheralConnParamUpdateReq -> 主机接收到并且同意(协议栈自动完成)-> 同一连接事件末尾:主机进GAP_LINK_PARAM_UPDATE_EVENT 同时从机进 peripheralParamUpdateCB()

中间如果不同意,两边都不会发生。

结语

到这里,关于 BLE 蓝牙连接参数的内容基本全部讲清楚了,通过本文的学习,大家在以后应用中应该能够根据自己的应用适当的设置对应的参数。

当然,博主也是学习阶段,通过示例代码,以及参考了前辈们的文章,对于主机发起的参数更新请求,除了示例网上好像没有太多解释,如果文章中有错误,希望大家指出!

好了,本文就到这里,谢谢大家!

http://www.dtcms.com/a/442404.html

相关文章:

  • 手机版做我女朋友网站域名申请时间需要多久
  • 【ROS2学习笔记】URDF 机器人建模
  • 哈尔滨多语言网站建设jsp源码做网站
  • 【Linux学习笔记】线程概念和控制(三)
  • 第2集:技术选型的智慧:Flask vs FastAPI,GLM-4 vs GPT
  • 做pc端网站行业现状网站 建设设计方案
  • 【c++】初识STL和string类
  • 网站建设同行抄袭玖云建站系统
  • 24 小时开发 IDM 浏览器智能嗅探插件:从 0 到 1 的效率工具搭建指南
  • 如何查网站死链收费网站推广
  • 最好的图像编辑器有哪些?
  • 【开题答辩实录分享】以《基于Python的旅游网站数据爬虫研究》为例进行答辩实录分享
  • 深圳网站建设 设计科技网站维护属于什么部门
  • DAY25 综合案例
  • 计算机网络(三):物理层(通信基础、传输介质、物理层设备)
  • app优化网站怎么用手机搭建网站
  • 郑州网站建设灵秀网店代运营怎么做
  • 宝塔环境下upload目录按月增量同步至阿里云OSS自动化脚本
  • 公域流量转化困境下开源AI智能名片与链动2+1模式的S2B2C商城小程序应用研究
  • YOLO算法原理详解系列 第001期-YOLOv1 算法原理详解
  • 竞赛管理系统|基于SpringBoot和Vue的竞赛管理系统(源码+数据库+文档)
  • 镇江网站建设包括哪些传媒网站后台免费模板
  • linux学习笔记(13)文件操作
  • 爬虫反反爬1
  • 网站建设包括哪些服务济宁住房和城乡建设厅网站首页
  • 网站cms大全九江学网站建设
  • 【ROS2学习笔记】参数
  • 网站建设哪儿好营销策划方案的目的
  • 近世代数(抽象代数)详细笔记--群
  • Drawio 在软件开发中的应用实践:从 BPMN 编排到 Serverless 工作流自动部署