BLE协议栈基础回顾:GATT/GAP角色、连接事件、连接间隔、从机延迟

各位好,我是老周。做蓝牙低功耗这些年,我见过太多工程师在休眠唤醒场景下栽跟头——数据丢了、连接断了、功耗下不来。追根溯源,多半是对协议栈底层机制理解不够透。今天咱们花点时间,把GATT、GAP、连接事件这几个基础概念彻底捋一遍。

说白了,这一章就是给后续的休眠唤醒数据保真打地基。地基不牢,后面盖什么楼都得塌。

1. GAP角色:谁广播,谁扫描,谁连接

GAP(Generic Access Profile)定义了设备在无线层面的行为。我习惯把它理解成“蓝牙设备的社交礼仪”——谁先开口说话,谁负责倾听,谁主动建立联系。

GAP定义了四种角色:

角色 行为描述 典型场景
Broadcaster 只发广播包,不接收连接 信标、温度传感器(只上报)
Observer 只扫描广播包,不发起连接 扫描仪、网关监听
Peripheral 发广播,可被连接 手环、传感器节点(从设备)
Central 扫描并发起连接 手机、网关(主设备)
我的经验:在休眠唤醒场景下,Peripheral角色最需要关注。因为从设备要定期醒来发广播或维持连接,又要快速睡回去省电。角色选错了,后面的功耗优化全是白费。

2. GATT角色:谁提供服务,谁消费数据

GAP管的是“怎么连”,GATT管的是“连上以后怎么传数据”。GATT把数据组织成Service和Characteristic的树形结构。

GATT角色只有两个:

  • GATT Server:持有数据的一方,提供Service和Characteristic。比如传感器节点把温度值放在某个Characteristic里。
  • GATT Client:读取或写入数据的一方。比如手机App去读那个温度Characteristic。

注意,一个设备可以同时是Server和Client。我在一个项目中做过网关,它既作为Server给手机提供汇总数据,又作为Client去读传感器节点的数据。这种混合角色在复杂系统中很常见。

关键点:休眠唤醒模式下,GATT Server(通常是传感器节点)必须保证在睡眠期间,Client发起的读写请求不会导致数据损坏或服务崩溃。这涉及到后面要讲的属性缓存、CCCD状态保持等问题。

3. 连接事件:BLE通信的最小时间片

BLE不是连续传输的。它把时间切成一个个小片,每个片叫一个连接事件(Connection Event)。主设备和从设备只在连接事件里交换数据。

我画了一张图,帮你理解连接事件的结构:

连接事件时序结构 连接事件 n 连接事件 n+1 连接事件 n+2 连接事件 n+3 连接间隔 连接间隔 连接间隔 从机跳过 从机跳过 从机响应 从机延迟 = 2 时,从设备可以跳过前 2 个连接事件,在第 3 个事件才响应 这期间主设备仍会按时发送轮询包,但从设备可以保持睡眠

每个连接事件里,主设备先发一个包,从设备收到后回复。一来一回算一次数据交换。如果数据多,可以在同一个连接事件里连续发多个包,这叫连接事件内的数据包扩展。

避坑提醒:我曾经在一个项目中把连接事件内的数据包数量设得太大,结果从设备处理不过来,导致丢包。后来我限制每个连接事件最多发3个包,问题就解决了。别贪多,稳才是王道。

4. 连接间隔:功耗与实时性的天平

连接间隔(Connection Interval)是两个相邻连接事件之间的时间,单位是1.25ms的整数倍。范围从7.5ms到4s。

连接间隔怎么选?我总结了一个简单的权衡表:

连接间隔 功耗 实时性 适用场景
7.5ms ~ 15ms 高 高 音频、实时控制
30ms ~ 100ms 中 中 传感器数据采集
100ms ~ 1s 低 低 低功耗传感器、休眠唤醒
1s ~ 4s 极低 极低 电池供电、非实时上报

你想想看,连接间隔越大,从设备睡眠的时间就越长,功耗自然就低。但代价是数据延迟变大。在休眠唤醒模式下,我一般建议把连接间隔设在100ms到500ms之间,既能保证数据及时性,又能把平均电流压到微安级别。

5. 从机延迟:让从设备多睡一会儿

从机延迟(Slave Latency)是从设备可以跳过不响应的连接事件数量。范围是0到499,但不能让跳过后的总时间超过4s。

举个例子:连接间隔是100ms,从机延迟设为3。那么从设备可以连续跳过3个连接事件(共300ms),在第4个事件才必须响应。这300ms里,从设备可以安心睡觉。

核心价值:从机延迟是休眠唤醒模式下最重要的省电参数。它让从设备在不需要传数据时“合法地”跳过连接事件,而不是每次都醒来再假装没数据。我做过一个温湿度传感器项目,开启从机延迟后,平均功耗降低了60%以上。

但要注意,从机延迟不是越大越好。如果延迟太大,主设备可能认为从设备掉线了,触发连接超时。连接超时时间(Supervision Timeout)一般是连接间隔的若干倍,默认6秒左右。所以从机延迟的设置要保证:

连接间隔 × (从机延迟 + 1) < 连接超时时间

嗯,这个公式一定要记住。我见过有人把从机延迟设成499,连接间隔100ms,结果算下来总时间49.9秒,远超6秒的超时时间,连接秒断。排查了半天才发现是这个问题。

6. 参数之间的联动关系

连接间隔、从机延迟、连接超时时间这三个参数是联动的。我习惯用一张表来展示它们的关系:

参数 典型值 对功耗的影响 对数据保真的影响
连接间隔 100ms 越大越省电 越大延迟越高,可能丢包
从机延迟 3 ~ 10 越大越省电 过大可能导致连接超时
连接超时时间 6s 无直接影响 过小容易误断,过大反应慢

在后续章节中,我们会基于这些参数,设计一套休眠唤醒策略。既要保证GATT服务的数据不丢、不错、不乱,又要让电池用上一年半载。说白了,就是在功耗和可靠性之间找到那个“甜点”。

我的习惯:每次拿到一个新模块,我会先写一个小程序,把连接间隔和从机延迟设成不同组合,然后用逻辑分析仪抓包看实际行为。纸上谈兵不如动手验证,这是最笨也最有效的方法。

好了,这一章的基础概念就回顾到这里。记住GAP管连接、GATT管数据、连接事件是通信的最小单元、连接间隔和从机延迟是省电的两大法宝。后面我们会把这些知识串起来,解决休眠唤醒下的数据保真问题。