2. BLE协议栈架构:各层功能与功耗影响
BLE协议栈,说白了就是一套分层的通信规则。每一层各司其职,又互相影响功耗。我做了这么多年低功耗设计,最大的体会就是:不懂协议栈,就别谈低功耗。
今天咱们把BLE协议栈从下往上捋一遍。重点看每层是干什么的,以及它们怎么影响你的电池寿命。
2.1 整体架构一览
先看一张整体架构图,心里有个全局概念。
从下往上看:PHY → Link Layer → HCI → L2CAP → ATT/GATT/SM → APP。HCI是分界线,下面是Controller(硬件/固件),上面是Host(软件)。
嗯,这里要注意:功耗优化的主战场在Controller侧,但Host侧的软件策略同样能决定成败。
2.2 物理层(PHY)—— 最底层的功耗基础
物理层负责最原始的比特收发。说白了就是天线怎么发信号、收信号。
BLE在2.4GHz频段工作,有40个信道。其中3个是广播信道(37/38/39),37个是数据信道。
| 参数 | BLE 1M PHY | BLE 2M PHY | BLE Coded PHY (S=2) | BLE Coded PHY (S=8) |
|---|---|---|---|---|
| 速率 | 1 Mbps | 2 Mbps | 500 kbps | 125 kbps |
| 传输时间(同数据量) | 基准 | 减半 | 翻倍 | 8倍 |
| 接收灵敏度 | -96 dBm | -93 dBm | -99 dBm | -103 dBm |
| 功耗影响 | 中等 | 较低(时间短) | 较高(时间长) | 最高(时间长) |
但别盲目追求高速。Coded PHY虽然慢,但灵敏度高。信号差的时候,重传更耗电。我曾经有个项目,在室内环境用2M PHY,结果重传率高达30%,功耗反而比用Coded PHY还高。
2.3 链路层(Link Layer)—— 功耗控制的核心
链路层是BLE功耗设计的心脏。它负责设备发现、连接建立、数据收发、以及最重要的——睡眠调度。
链路层定义了5种状态:
- Standby —— 啥也不干,最省电
- Advertising —— 广播,让别人发现自己
- Scanning —— 扫描,找别人
- Initiating —— 发起连接
- Connection —— 已连接
功耗从低到高:Standby < Connection(空闲时) < Advertising < Scanning < Connection(收发数据时)。
这里有个关键概念——连接间隔(Connection Interval)。连接后,主设备和从设备每隔这个时间交换一次数据。间隔越长,设备睡眠时间越长,越省电。
| 连接间隔 | 典型场景 | 平均电流(从设备) |
|---|---|---|
| 7.5 ms | 音频、实时控制 | ~500 μA |
| 30 ms | 传感器数据流 | ~100 μA |
| 100 ms | 周期性上报 | ~30 μA |
| 1 s | 低功耗传感器 | ~5 μA |
我记得有个项目,客户要求传感器数据每秒上报一次。我一开始用100ms连接间隔,结果平均电流30μA。后来改成1s间隔,降到5μA。客户说「数据没丢,延迟也能接受」。嗯,这就是链路层调参的魅力。
2.4 HCI(主机控制器接口)—— 分界线上的功耗陷阱
HCI是Host和Controller之间的通信接口。常见的有UART、SPI、USB。
HCI本身不直接消耗太多射频功耗,但它是数据传输的瓶颈。如果HCI接口速率低,数据包在Host侧排队,Controller就得一直等着,没法进睡眠。
我踩过一个坑:用某个蓝牙模组,HCI用UART 115200波特率。每次传20字节数据,UART传输就要花约1.7ms。这期间Controller不能睡。后来改成1M波特率,传输时间降到0.2ms,整体功耗降了12%。
2.5 L2CAP(逻辑链路控制与适配协议)—— 数据打包与分段
L2CAP负责把上层数据打包成链路层能处理的格式。它支持MTU协商、分段重组、以及面向连接的信道。
功耗影响主要体现在MTU大小上。MTU越大,每个包能带的数据越多,传输效率越高。
举个例子:你要传100字节数据。
- MTU=23(默认):需要拆成5个包,每个包还有额外开销
- MTU=247:1个包搞定
包越多,射频开启次数越多,功耗越高。我建议在应用层主动协商大MTU。很多开发者不知道,BLE默认MTU只有23字节,但大部分芯片支持到247甚至更大。
2.6 ATT(属性协议)与 GATT(通用属性协议)—— 数据交互的规范
ATT定义了如何读写「属性」——也就是数据的最小单元。GATT则定义了这些属性怎么组织成服务、特征值。
功耗影响主要来自数据交互的次数。ATT的每个操作(读、写、通知)都需要一次或多次链路层数据交换。
举个例子:
- Read:发请求 → 等响应 → 收数据。一来一回,至少两个连接事件。
- Write:发数据 → 等确认。也是一来一回。
- Notification:直接发,不需要确认。一个连接事件搞定。
所以,能用Notification就别用Write。能批量读就别一个个读。
我做过一个温湿度计,原来每5秒用Read读一次数据。后来改成每5秒用Notification推送一次。功耗从15μA降到8μA。省了一半。
2.7 SM(安全管理层)—— 安全与功耗的平衡
SM负责配对、绑定、加密。安全很重要,但加密解密是要消耗算力的。
BLE支持几种配对方式:
| 配对方式 | 安全等级 | 功耗影响 |
|---|---|---|
| Just Works | 低(无MITM保护) | 低 |
| Passkey Entry | 中 | 中 |
| Numeric Comparison | 高 | 中 |
| OOB(带外) | 高 | 取决于OOB方式 |
配对过程本身是一次性的,功耗影响不大。但加密后的数据收发有影响。每次加密数据包,芯片需要做AES-128计算。虽然现代蓝牙芯片硬件加速了,但算力消耗还是有的。
嗯,SM还有一个容易被忽略的点——绑定信息存储。如果设备频繁重新配对,每次配对都要重新交换密钥,功耗就上去了。我建议把绑定信息存到非易失存储器里,下次连接直接复用。
2.8 各层功耗影响总结
最后一张表,把各层的功耗影响和优化方向串起来:
| 协议层 | 主要功耗影响因素 | 优化方向 |
|---|---|---|
| PHY | 速率、灵敏度、传输时间 | 根据链路预算选PHY,信号好时用2M |
| Link Layer | 连接间隔、广播间隔、扫描窗口 | 拉大连接间隔,减少广播频次 |
| HCI | 接口速率、数据排队 | 提高UART/SPI速率,减少等待 |
| L2CAP | MTU大小、分包数量 | 协商大MTU,减少包数 |
| ATT/GATT | 操作次数、交互模式 | 用Notification代替Read/Write |
| SM | 加密计算、配对频率 | 按需加密,持久化绑定信息 |
做BLE低功耗设计,说白了就是在各层之间找平衡。物理层快一点,链路层睡久一点,应用层少交互一点——每一层省一点,整体效果就出来了。
我做了这么多项目,最深的体会是:没有银弹。每个场景都要具体分析。但只要你把协议栈各层的功耗影响摸透了,优化方向就清晰了。