蓝牙技术基础:蓝牙经典与低功耗蓝牙的区别、BLE协议栈架构、核心术语(GAP、GATT、Attribute、Characteristic等)
在开始BLE 5.0开发之前,必须先厘清蓝牙技术家族的整体脉络。许多初学者混淆“蓝牙”与“低功耗蓝牙”,导致选型错误、协议理解偏差。本章将从物理层差异、协议栈分层、核心抽象模型三个维度,建立完整的BLE知识框架。理解GAP与GATT的分工,是后续开发服务端(Server)与客户端(Client)应用的基础。
2.1 蓝牙经典与低功耗蓝牙的本质区别
蓝牙经典(BR/EDR)与低功耗蓝牙(BLE)虽然共享“蓝牙”名称,但设计哲学截然不同。经典蓝牙面向持续音频流和高吞吐量传输,而BLE面向间歇性小数据包传输,以极低功耗换取数十毫秒级的连接延迟。两者在物理层、协议栈、功耗模型上均有根本差异。
| 对比维度 | 蓝牙经典 (BR/EDR) | 低功耗蓝牙 (BLE) |
|---|---|---|
| 物理层调制 | GFSK,79个信道,1MHz带宽 | GFSK,40个信道,2MHz带宽 |
| 最大数据速率 | 2 Mbps (EDR) | 2 Mbps (BLE 5.0) |
| 拓扑结构 | 微微网(1主7从) | 广播/扫描 + 连接(多对多) |
| 功耗目标 | 毫瓦级(持续传输) | 微瓦级(休眠+唤醒) |
| 连接建立时间 | 约100ms | 约3-10ms |
| 典型应用 | 蓝牙耳机、车载免提 | 穿戴设备、传感器、信标 |
从开发视角看,经典蓝牙使用RFCOMM/SPP等串口模拟协议,而BLE使用ATT/GATT面向属性操作。这意味着BLE的数据交互不是“流式”的,而是“属性读写”模式。例如心率传感器将心率值放在一个Characteristic中,手机端读取该值即可,无需建立持续的数据通道。
2.2 BLE协议栈架构:从物理层到应用层
BLE协议栈分为三大部分:控制器(Controller)、主机(Host)和应用层(Application)。控制器包含物理层(PHY)和链路层(LL),负责射频收发、信道选择、状态机管理;主机包含L2CAP、ATT、GATT、SMP等协议,负责逻辑信道复用、属性操作和安全配对;应用层则直接面向开发者,使用GAP和GATT API。
链路层是BLE的核心,定义了五种状态:待机(Standby)、广播(Advertising)、扫描(Scanning)、发起连接(Initiating)、已连接(Connected)。广播者(Advertiser)周期性发送广播包,扫描者(Scanner)监听广播包,发起者(Initiator)可向广播者发起连接请求。连接建立后,双方以固定间隔跳频通信,该间隔由连接参数决定。
// 典型BLE连接参数(以nRF5 SDK为例)
// 连接间隔:7.5ms ~ 4s,默认推荐 30-50ms
// 从机延迟:0 ~ 499,允许从机跳过若干连接事件
// 超时时间:100ms ~ 32s,超过则断开连接
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS)
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(50, UNIT_1_25_MS)
#define SLAVE_LATENCY 0
#define SUPERVISION_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
L2CAP层负责将上层数据封装为PDU并分发到对应协议通道。ATT层定义了客户端-服务器模型,客户端发送请求,服务器返回响应。GATT层则基于ATT构建了服务(Service)、特征(Characteristic)的层级结构,使数据组织标准化。
2.3 核心术语:GAP、GATT、Attribute、Characteristic
GAP(Generic Access Profile)定义了设备如何被发现和连接。它规定了两种角色:外围设备(Peripheral)和中央设备(Central)。外围设备广播数据,中央设备扫描并主动连接。GAP还管理广播数据格式、连接参数协商、配对与绑定流程。
GATT(Generic Attribute Profile)定义了连接后如何交换数据。它基于ATT协议,将数据组织为服务(Service)和特征(Characteristic)。一个服务包含多个特征,每个特征包含一个值(Value)和若干描述符(Descriptor)。例如心率服务(0x180D)包含心率测量特征(0x2A37),该特征的值是心率数据,描述符则说明数据格式。
Attribute是GATT的最小数据单元,包含四个字段:句柄(Handle)、类型(UUID)、权限(Permissions)和值(Value)。句柄是16位地址,用于定位属性;UUID标识属性类型,标准UUID为16位(如0x2A37),自定义UUID为128位;权限控制读写访问;值存储实际数据。
2.4 实战场景:构建一个BLE心率传感器服务
假设我们要开发一个BLE心率胸带,需要将心率数据实时发送给手机App。首先定义GATT服务:使用标准心率服务UUID(0x180D),包含心率测量特征(0x2A37)。该特征支持通知(Notification),即设备主动推送数据,无需手机轮询。
实现步骤:
- 初始化协议栈:配置PHY为1M或2M,设置广播参数(间隔100ms,可连接)
- 注册GATT服务:添加心率服务,添加心率测量特征,设置属性为读+通知
- 配置CCCD:使能客户端特征配置描述符,允许手机订阅通知
- 启动广播:广播包中包含设备名称和心率服务UUID
- 处理连接事件:连接建立后,每秒钟读取传感器数据并发送通知
// 伪代码示例:发送心率通知
uint8_t heart_rate = read_sensor();
uint8_t flags = 0x00; // 心率格式为UINT8
uint8_t data[2] = {flags, heart_rate};
gatt_server_send_notification(hr_meas_handle, data, sizeof(data));
手机端作为Central,扫描到设备后连接,发现服务,找到心率测量特征,订阅通知,即可实时接收数据。整个过程涉及GAP的连接管理和GATT的数据交互,两者协同工作。
2.5 常见误区与总结复盘
误区一:认为BLE只能传输小数据。实际上BLE 5.0支持长达255字节的数据包,且通过LE Coded PHY可实现更远距离传输。误区二:忽视广播数据格式。广播包中Service UUID的排列方式影响扫描端的解析效率,建议使用完整的128位UUID时采用“完整列表”格式,而非“部分列表”。误区三:忽略连接参数更新。默认连接间隔可能不适合所有场景,应根据功耗和实时性需求动态调整。
总结:BLE开发的核心是理解GAP管理连接生命周期,GATT管理数据交互。掌握Attribute的句柄、UUID、权限、值四要素,就能灵活设计自定义服务。下一阶段将深入BLE 5.0的新特性,包括2M PHY、Coded PHY、广播扩展等,这些特性将进一步提升吞吐量和覆盖范围。