1. 课程导论:BLE低功耗设计概述、GATT协议栈架构、休眠唤醒机制的价值
各位工程师朋友,欢迎来到《BLE GATT服务休眠唤醒低功耗设计实战》的第一章。
做蓝牙低功耗(BLE)开发这些年,我见过太多产品死在功耗上。功能都调通了,连上了,跑起来了,结果一测电流——几十毫安。老板问:“这跟经典蓝牙有什么区别?” 嗯,场面一度很尴尬。
所以这门课,咱们不聊虚的。直接切入BLE低功耗设计的核心痛点:GATT服务怎么在休眠唤醒的节奏下,把功耗压到极致。
1.1 BLE低功耗设计:不只是“省电”两个字
很多人觉得BLE低功耗就是“少发数据”、“把广播间隔拉长”。其实没那么简单。
BLE的低功耗,本质上是一种时间分片的工作哲学。设备大部分时间在睡觉,醒来快速干完活,再睡回去。这个“睡-干-睡”的节奏,决定了你的产品能撑一周、一个月,还是一年。
我个人习惯把BLE功耗拆成三块来看:
- 连接事件功耗:主从设备约定时间点交换数据,这是BLE最核心的功耗来源。
- 广播/扫描功耗:设备还没建立连接时,靠广播包刷存在感。刷得越勤,电掉得越快。
- 空闲态功耗:啥也不干的时候,芯片能不能进入深度睡眠。很多新手栽在这一块。
核心观点:BLE低功耗设计的本质,不是“少干活”,而是“干完活立刻睡,睡到下次该干活再醒”。GATT服务的设计,必须围绕这个节奏来展开。
我在项目中遇到过一款智能门锁,连接态功耗做到20μA以下,但客户反馈电池只能用两个月。查了半天,问题出在GATT服务上——每次唤醒后,服务要枚举所有特征值,耗时200ms。这200ms里,芯片全速跑,电流十几毫安。一天唤醒几十次,功耗全耗在“起床穿衣服”上了。
你看,GATT服务的设计,直接决定了休眠唤醒的效率。
1.2 GATT协议栈架构:从Profile到Attribute
聊休眠唤醒之前,得先把GATT的底子打牢。GATT(Generic Attribute Profile)是BLE应用层的核心框架。说白了,它定义了数据怎么组织、怎么读写、怎么通知。
GATT的架构,我习惯用“三层嵌套”来理解:
- Profile(服务集合):一个产品通常包含多个服务。比如心率计有心率服务、电池服务、设备信息服务。
- Service(服务):一组相关特征值的集合。每个服务有唯一的UUID。
- Characteristic(特征值):真正存数据的地方。包含值、属性、描述符。
你想想看,GATT本质上就是一棵树。树根是Profile,树枝是Service,树叶是Characteristic。数据就挂在树叶上。
下面这张图,帮你把GATT协议栈的层次关系看清楚:
这张图里,从上到下是数据封装的过程。应用层的数据,经过GATT组织成服务/特征值,再通过ATT协议挂到属性表上,最后通过L2CAP和Link Layer发出去。
反过来,接收数据时,数据从空中进来,一路解包,最终回到应用层。
避坑提示:很多开发者把GATT服务和ATT属性表混为一谈。其实GATT是“逻辑组织”,ATT是“物理存储”。GATT告诉你数据长什么样,ATT告诉你数据放在哪、怎么访问。休眠唤醒时,我们操作的是ATT属性表,但设计时要按GATT的层次来规划。
1.3 GATT Profile的结构细节
咱们再深入一层。一个典型的GATT服务,内部长这样:
| 层级 | 元素 | 说明 | 休眠唤醒关注点 |
|---|---|---|---|
| Service | UUID + 包含的特征值列表 | 服务的唯一标识,如0x180D(心率) | 服务声明属性在唤醒后需快速可访问 |
| Characteristic | 声明 + 值 + 描述符 | 声明包含属性、UUID、值句柄 | 值句柄的缓存策略影响唤醒速度 |
| Value | 实际数据(最长512字节) | 传感器读数、状态标志等 | 唤醒后是否需要重新读取?还是用缓存? |
| Descriptor | CCC配置、用户描述等 | CCC决定是否使能通知/指示 | CCC状态必须在休眠期间保持 |
这里有个关键点:CCC(Client Characteristic Configuration)描述符。它决定了设备要不要主动给手机发数据。很多低功耗设计翻车,就是因为休眠后CCC状态丢了,醒来后手机收不到通知,还以为设备死了。
我曾经调试过一个血压计项目,休眠后唤醒,手机收不到测量结果。查了两天,发现是CCC描述符在休眠时被清空了。解决方案很简单:把CCC状态保存在非易失区,唤醒后恢复。但就是这个小细节,功耗曲线直接从平滑变成锯齿状。
1.4 休眠唤醒机制的价值:为什么这门课值得你花时间?
好,咱们回到最根本的问题:为什么要在GATT服务层面专门讲休眠唤醒?
直接说结论:BLE芯片的休眠电流已经做到1μA以下了,但你的产品功耗还是下不来。瓶颈不在芯片,在软件架构。
我见过太多案例:
- 芯片休眠电流0.5μA,整机平均功耗50μA。差了两个数量级。
- 问题出在哪?GATT服务在唤醒后做了大量冗余操作:重新注册服务、重新枚举特征值、重新建立安全连接。
- 这些操作,每多一次,就多耗几毫秒。几毫秒的全速运行电流,抵得上几小时的休眠。
休眠唤醒机制的价值,可以归纳为三点:
- 缩短唤醒窗口:从“醒来做所有事”变成“醒来只做必要事”。GATT服务的初始化流程必须精简。
- 保持连接状态:休眠期间不丢连接参数、不丢CCC状态、不丢服务缓存。醒来后直接恢复,不用重新握手。
- 按需加载服务:不是所有服务都需要在每次唤醒时加载。低频服务可以延迟加载,甚至只在需要时加载。
警告:不要以为休眠唤醒只是“调一下睡眠模式”那么简单。GATT服务的状态机、属性表的缓存策略、连接参数的协商时机,每一个环节都可能成为功耗黑洞。这门课后面会逐一拆解。
嗯,说到这里,我想起一个典型的对比案例。同样是温湿度传感器,A方案用标准GATT服务,每次唤醒都重新注册所有特征值,平均功耗12μA。B方案做了休眠唤醒优化,服务状态保持,唤醒后只更新数据,平均功耗2.3μA。同样的芯片,同样的传感器,功耗差了5倍。
这就是咱们这门课要解决的问题。
1.5 本章小结
这一章,咱们把BLE低功耗设计的核心逻辑、GATT协议栈的层次结构、以及休眠唤醒机制的价值捋了一遍。
记住三个关键点:
- BLE低功耗的本质是时间分片,GATT服务必须适配这个节奏。
- GATT架构是Profile → Service → Characteristic的三层树形结构,休眠唤醒时要关注每一层的状态保持。
- 休眠唤醒优化的价值在于缩短唤醒窗口、保持连接状态、按需加载服务。