3. BLE协议栈架构:Controller与Host分层、GAP与GATT角色、BLE连接建立流程

BLE协议栈,说白了就是一套软件分层规范。我刚开始接触蓝牙时,总觉得这东西很玄乎。后来调了几个项目才明白——分层设计就是为了让咱们工程师能各司其职,不用从头造轮子。

这一章,咱们把BLE协议栈拆开来看。重点就三个:Controller与Host怎么分工、GAP和GATT到底管什么、连接是怎么一步步建立起来的。

3.1 Controller与Host:协议栈的两大块

BLE协议栈分两层:Controller(控制器)和Host(主机)。中间通过HCI(Host Controller Interface)通信。你想想看,这就像把射频硬件和上层应用逻辑隔离开。

核心分工:

  • Controller:负责物理层、链路层。说白了就是管发数据、收数据、定时、跳频这些硬活。
  • Host:负责逻辑链路控制、属性协议、安全管理、GAP/GATT。这些是软件层面的东西。
  • HCI:两者之间的管道。可以是UART、SPI、USB。

我在一个穿戴项目里遇到过一个问题:设备偶尔断连,抓包发现是HCI通信超时。后来排查发现是UART波特率不匹配,Controller发过来的事件包Host没及时收。嗯,这种坑调一次就记住了。

分层 包含模块 典型实现
Controller PHY、LL、RF Nordic nRF52840的无线电硬件 + 固件
Host L2CAP、SM、ATT、GAP、GATT Zephyr或FreeRTOS上的协议栈软件
HCI 命令/事件/数据包 UART传输,典型波特率115200或更高

实际项目中,很多SoC把Controller和Host做在同一颗芯片里,比如Nordic、TI的CC26xx系列。但有些场景需要分开——比如手机里,Host跑在应用处理器上,Controller跑在蓝牙芯片上。这时候HCI就特别关键。

3.2 GAP与GATT:两种角色,两种职责

GAP和GATT,这两个词初学者容易搞混。我简单说:GAP管“能不能连”,GATT管“连上后能干什么”。

3.2.1 GAP(通用访问规范)

GAP定义了设备的角色和广播行为。说白了就是:你是谁?你能被谁发现?

  • Broadcaster:只发广播,不连。比如信标。
  • Observer:只收广播,不连。比如扫描器。
  • Peripheral:从设备,发广播,等待连接。比如传感器。
  • Central:主设备,扫描并发起连接。比如手机。

我个人的习惯:做低功耗产品时,尽量让设备做Peripheral角色。因为Peripheral可以控制广播间隔和连接间隔,功耗更好调。Central角色要一直扫描,功耗很难压下去。

3.2.2 GATT(通用属性规范)

GATT定义了连接后的数据交互方式。它基于ATT(属性协议),把数据组织成Service(服务)和Characteristic(特征值)。

举个例子:一个心率传感器,它有一个“心率服务”,里面包含“心率测量值”这个特征值。手机连上后,通过GATT读这个特征值,就能拿到心率数据。

GATT角色 说明 典型设备
GATT Server 提供数据的一方,拥有属性表 心率传感器、温湿度计
GATT Client 请求数据的一方,读写属性 手机App、网关

注意:GAP角色和GATT角色是独立的。一个Peripheral设备可以是GATT Server,也可以是GATT Client。我在一个项目中做过双向数据透传,设备既是Server(提供状态),又是Client(读取配置),这种场景很常见。

3.3 BLE连接建立流程

连接建立,我把它拆成四个步骤。每一步都有坑,咱们一个一个说。

  1. 广播:Peripheral在三个广播信道(37/38/39)上发广播包。广播间隔一般20ms到10.24s可配。
  2. 扫描:Central在广播信道上监听。扫描窗口和扫描间隔决定了发现速度。
  3. 发起连接:Central收到广播后,发送CONNECT_REQ。这个包包含了连接参数:连接间隔、延迟、超时时间。
  4. 连接建立:双方切换到数据信道,按约定的连接间隔进行数据交互。

我曾经踩过的坑:连接间隔设得太小(比如7.5ms),导致设备功耗飙升。后来改成30ms,功耗降了60%。你想想看,连接间隔直接决定了射频唤醒频率,这是低功耗调优的第一道关口。

下面这张图,把整个流程画清楚了:

BLE连接建立流程 BLE连接建立流程 Peripheral Central ① 广播 ② 扫描 广播包(ADV_IND) ③ 发起连接 CONNECT_REQ ④ 连接建立 ④ 连接建立 数据信道交互 连接间隔决定功耗

3.4 连接参数与低功耗调优

连接建立后,真正影响功耗的是三个参数:

  • 连接间隔(Connection Interval):两次数据交互之间的时间。范围7.5ms到4s。间隔越大,功耗越低,但延迟也越大。
  • 从设备延迟(Slave Latency):从设备可以跳过几次连接事件而不丢连接。比如延迟设为4,意味着可以跳过4次连接事件,省电。
  • 监督超时(Supervision Timeout):超过这个时间没收到包,就认为连接断了。一般设成连接间隔的几倍。
参数 典型值 对功耗的影响
连接间隔 30ms ~ 100ms 间隔越大,射频唤醒越少,功耗越低
从设备延迟 0 ~ 499 延迟越大,设备可以睡更久
监督超时 100ms ~ 32s 太短容易误断连,太长反应慢

我的调优经验:对于传感器类产品,连接间隔设100ms,从设备延迟设3,监督超时设2s。这样平均电流能控制在10μA以下。如果是音频或OTA,连接间隔得压到15ms以内,但功耗会翻好几倍。

3.5 小结

这一章咱们把BLE协议栈的骨架搭起来了。Controller管硬件,Host管逻辑,GAP管发现,GATT管数据。连接建立的四步流程,每一步都有参数可以调。记住一点:低功耗不是靠一个参数,而是靠整体参数的平衡。