第1章:BLE协议栈架构概览
大家好,我是你们的老朋友。今天咱们开始聊蓝牙BLE协议栈。
说实话,我第一次接触BLE协议栈的时候,看着那一堆缩写——PHY、LL、HCI、L2CAP、ATT、GATT、GAP——头都大了。这玩意儿到底怎么串起来的?每个层到底干啥的?
别急,我带你一层层剥开它。
1.1 物理层(PHY)——最底层的“无线电”
物理层,说白了就是负责发信号和收信号的那部分硬件。它决定了你的蓝牙芯片用哪个频段、怎么调制、传输速率多少。
BLE工作在2.4GHz ISM频段,这个频段大家都能用——Wi-Fi、Zigbee、微波炉……嗯,你没听错,微波炉也在这频段。所以干扰是家常便饭。
BLE物理层有几个关键参数:
- 频段:2.4 - 2.4835 GHz
- 信道数:40个信道,每个2MHz宽
- 调制方式:GFSK(高斯频移键控)
- 传输速率:1 Mbps(BLE 4.x/5.0),2 Mbps(BLE 5.0+)
我个人的经验:在共享单车项目里,物理层最坑的是信号衰减。单车停在金属车棚里,信号直接掉一半。后来我们加了天线匹配电路,才勉强搞定。
1.2 链路层(LL)——连接的管理者
链路层是协议栈里最核心的一层。它负责设备发现、连接建立、数据包重传、加密等等。
你想想看,两个蓝牙设备怎么知道对方存在?怎么建立连接?怎么保证数据不丢?这些都是链路层干的活。
链路层有几个重要概念:
- 状态机:Standby、Advertising、Scanning、Initiating、Connection
- 角色:Master(主机)和 Slave(从机)
- 数据包格式:Preamble + Access Address + PDU + CRC
避坑指南:我曾经在调试连接断开问题时,查了三天代码,最后发现是链路层的连接间隔(Connection Interval)设得太短,导致从机来不及处理。记住,连接间隔不是越小越好。
1.3 主机控制接口(HCI)——软硬件的分界线
HCI是协议栈里一个特殊的存在。它不处理业务逻辑,它只是“传话的”。
HCI定义了主机(Host)和控制器(Controller)之间的通信协议。主机通常是CPU上跑的软件栈,控制器是蓝牙芯片里的固件。
HCI的命令和事件大概有几十种,常用的包括:
- LE Set Advertising Parameters:设置广播参数
- LE Create Connection:发起连接
- LE Read Remote Features:读取对方特性
嗯,这里要注意:HCI的通信方式可以是UART、USB、SPI等。共享单车里最常见的是UART,因为成本低、实现简单。
1.4 L2CAP——数据的分包与重组
L2CAP全称是逻辑链路控制与适配协议。名字很绕,但功能很简单——它负责把上层的大数据包拆成链路层能处理的小包,反过来也负责把小包拼成大包。
为什么需要L2CAP?因为链路层的数据包最大只有几十个字节(BLE 4.x是27字节,BLE 5.0可以到251字节)。你上层要发一个几百字节的配置文件,不拆不行。
L2CAP还提供:
- 信道复用:多个上层协议共用同一个链路层连接
- 分段与重组:大包拆小包,小包拼大包
- 流控:防止发送方太快,接收方来不及处理
我记得有一次,共享单车的固件升级包有几十KB,L2CAP分段参数没调好,导致升级成功率只有60%。后来把MTU(最大传输单元)从23字节调到247字节,成功率直接飙到99%。
1.5 ATT——属性协议
ATT是Attribute Protocol的缩写。它定义了一种“客户端-服务器”模型,用来读写设备上的数据。
在BLE里,数据是以“属性”的形式存在的。每个属性都有一个UUID、一组权限、以及实际的数据值。
ATT的操作包括:
- Read Request/Response:读属性
- Write Request/Response:写属性(需要确认)
- Write Command:写属性(不需要确认)
- Notify/Indicate:服务器主动通知客户端
说白了,ATT就是BLE世界里的“读写接口”。你手机读单车锁的状态,就是通过ATT读一个属性。
1.6 GATT——属性协议的上层封装
GATT全称是通用属性协议。它是在ATT之上定义的一套规范,用来组织和管理属性。
GATT引入了几个重要概念:
- Service(服务):一组相关属性的集合,比如“电池服务”、“设备信息服务”
- Characteristic(特征):一个具体的属性,包含值和描述符
- Descriptor(描述符):对特征的额外描述,比如单位、范围等
举个例子:共享单车的“开锁”功能,在GATT里就是一个Characteristic。手机往这个Characteristic写一个“开锁指令”,单车收到后执行开锁动作。
我的建议:设计GATT服务时,尽量用标准的UUID(比如蓝牙SIG定义的),不要自己造轮子。标准服务兼容性好,调试工具也支持。
1.7 GAP——设备发现与连接管理
GAP全称是通用访问协议。它负责设备如何被发现、如何建立连接、以及连接后的角色管理。
GAP定义了四种角色:
| 角色 | 说明 | 共享单车场景 |
|---|---|---|
| Broadcaster | 只发送广播,不接收连接 | 不太常用 |
| Observer | 只扫描广播,不发起连接 | 不太常用 |
| Peripheral | 发送广播,等待连接 | 单车锁(从机) |
| Central | 扫描广播,发起连接 | 手机(主机) |
GAP还定义了广播数据格式、扫描参数、连接参数等。这些参数直接影响功耗和连接速度。
注意:GAP的广播间隔和连接间隔是功耗和响应速度的平衡点。广播间隔越短,设备被发现越快,但功耗越高。共享单车一般设100ms左右,既保证用户扫码后能快速发现,又不至于把电池耗光。
小结
好了,这一章我们把BLE协议栈的七层结构过了一遍。从最底层的PHY到最上层的GAP,每一层都有自己的职责。
你可能会问:这么多层,实际开发中都要自己写吗?
当然不是。大部分蓝牙芯片厂商都提供了完整的协议栈,你只需要调用API就行。但理解每一层的作用,能帮你快速定位问题——比如连接不上,是GAP的问题还是LL的问题?数据传不过去,是L2CAP分段错了还是ATT权限不对?
下一章,咱们深入物理层,聊聊天线设计和信号覆盖那些事。
公众号:蓝海资料掘金营,微信 deep3321