BLE 协议栈架构:分层模型与各层功能

做蓝牙开发这么多年,我见过不少新手一上来就扎进代码里,结果被各种术语搞得晕头转向。其实,理解 BLE 协议栈的分层模型,就像看懂一栋大楼的结构图——你不需要知道每块砖怎么烧的,但必须知道哪层是承重墙、哪层是水电管道。

BLE 协议栈分三层:Controller(控制器)、Host(主机)、Application(应用)。说白了,这就是一个从硬件到软件的逐层抽象。我习惯把 Controller 比作「收发室」,Host 比作「翻译官」,Application 就是「老板」——老板只管发指令,具体怎么传、怎么编解码,下面的人搞定。

分层模型总览

先看一张整体架构图,后面我们再一层层拆开讲。

核心要点:分层设计的最大好处是解耦。芯片厂只管 Controller,协议栈公司做 Host,应用开发者写 Application。各干各的,互不干扰。

BLE 协议栈分层架构 Application(应用层) 用户业务逻辑、Profile 实现、数据交互 Host(主机层) GAP(通用访问规范) GATT(通用属性规范) ATT(属性协议) L2CAP(逻辑链路控制) SM(安全管理) HCI(主机控制器接口) Controller(控制器层) LL(链路层) 状态机、数据包、加密 PHY(物理层) 2.4GHz 射频、调制解调 软件 硬件

Controller 层:硬件的看门人

Controller 层是离芯片最近的一层,直接操作射频硬件。它包含两个子层:PHY(物理层)和LL(链路层)。

PHY(物理层)

PHY 负责最原始的比特流收发。BLE 工作在 2.4GHz ISM 频段,使用 GFSK 调制。速率方面,BLE 4.x 是 1Mbps,BLE 5.0 引入了 2Mbps 和 125kbps(长距离模式)。

我的经验:有一次做穿戴设备,天线匹配没调好,PHY 层丢包率高达 30%。后来发现是 PCB 走线阻抗不匹配。记住,PHY 层的问题往往不是协议栈能解决的,得找射频工程师。

LL(链路层)

LL 层是 Controller 的核心。它管理着五个状态机:Standby、Advertising、Scanning、Initiating、Connection。说白了,LL 层决定了设备什么时候发、什么时候收、怎么重传。

LL 层还负责数据包封装、CRC 校验、加密(AES-CCM)。我见过有人把 LL 层的重传机制当成「万能保险」,结果在干扰严重的环境里,重传次数设得太大,功耗直接翻倍。

注意:LL 层的连接间隔(Connection Interval)直接影响功耗和吞吐量。间隔越小,数据越快,但功耗越高。我一般建议:对功耗敏感的产品,间隔设在 30ms-50ms;对实时性要求高的,可以压到 7.5ms。

Host 层:协议的翻译官

Host 层跑在 CPU 上,通常是软件实现。它把 Controller 收上来的原始数据包,翻译成应用能理解的格式。Host 层包含五个子层:HCI、L2CAP、SM、ATT、GATT、GAP。

HCI(主机控制器接口)

HCI 是 Host 和 Controller 之间的「桥梁」。它定义了命令、事件、数据的传输格式。常见的物理传输方式有 UART、USB、SDIO。

我记得早期做项目时,HCI 的 UART 波特率设成了 115200,结果数据量大时频繁丢包。后来改成 921600,问题解决。嗯,HCI 的传输速率往往是瓶颈。

L2CAP(逻辑链路控制与适配协议)

L2CAP 负责把上层的数据拆成适合 LL 层传输的小包,也负责把收到的包重组回去。它还提供了分段重组(SAR)和协议复用功能。

举个例子:你通过 BLE 传一张图片,L2CAP 会把图片数据切成 20 字节左右的 ATT 包,再交给 LL 层发送。接收端再拼回去。

SM(安全管理)

SM 负责配对、绑定、加密。BLE 的配对方式有三种:Just Works(无显示)、Passkey Entry(输入 PIN)、Out of Band(NFC 等)。

避坑指南:我曾经做过一个门锁项目,用了 Just Works 配对,结果被安全审计指出中间人攻击风险。后来改成 Passkey Entry + 显示确认,才通过认证。安全等级别省,省了就是给自己挖坑。

ATT(属性协议)

ATT 定义了客户端-服务器模型。服务器端维护一组属性(Attribute),客户端通过读写这些属性来交互数据。每个属性有:句柄(Handle)、类型(UUID)、权限(Permissions)、值(Value)。

ATT 的操作包括:Read、Write、Notify、Indicate。Notify 不需要确认,速度快;Indicate 需要确认,更可靠。你想想看,心率数据用 Notify 就够了,但固件升级的写操作必须用 Indicate。

GATT(通用属性规范)

GATT 在 ATT 之上定义了更高级的数据组织方式。它引入了Service(服务)和Characteristic(特征)的概念。一个 Service 包含多个 Characteristic,每个 Characteristic 有对应的 Value 和 Descriptor。

举个例子:心率服务(Heart Rate Service)包含心率测量特征(Heart Rate Measurement),这个特征的值就是实时心率数据。

GAP(通用访问规范)

GAP 定义了设备如何被发现、如何建立连接。它规定了四种角色:Broadcaster、Observer、Peripheral、Central。Peripheral 发广播,Central 扫描并连接。

GAP 还定义了广播数据包的格式。广播包最多 31 字节,扫描响应包也是 31 字节。空间很宝贵,得精打细算。

角色 功能 典型设备
Broadcaster 只发广播,不连接 信标(Beacon)
Observer 只扫描广播,不连接 扫描仪
Peripheral 发广播,等待连接 传感器、手环
Central 扫描并发起连接 手机、平板

Application 层:老板的指令

Application 层就是你的业务代码。它调用 GAP 和 GATT 的 API,实现具体的产品功能。比如:温度计 App 读取温度特征值,门锁 App 发送开锁指令。

这一层不需要关心底层怎么传的,只需要知道「我要读哪个特征值」「我要写什么数据」。说白了,这就是分层设计给开发者带来的福利。

协议栈与芯片的关系

很多人搞不清协议栈和芯片的关系。我简单说一下:芯片是硬件载体,协议栈是软件灵魂。

Controller 层通常固化在芯片的 ROM 或 Flash 里,由芯片厂商提供。Host 层可以是芯片自带的,也可以是第三方协议栈(如 Zephyr、BlueZ、FreeRTOS+BLE)。Application 层完全由你写。

举个例子:Nordic nRF52840 芯片,它的 Controller 是硬件实现的,Host 可以用 Nordic 的 SoftDevice,也可以用开源协议栈。TI 的 CC2640 类似,Controller 在 ROM 里,Host 在 Flash 里。

我的建议:选芯片时,先看它的协议栈是否成熟。有些小厂的芯片虽然便宜,但协议栈 bug 多,调试起来生不如死。我踩过这个坑,后来老老实实换回 Nordic。

另外,协议栈的版本也很重要。BLE 4.2 引入了 LE Secure Connections,BLE 5.0 引入了 2Mbps 和长距离。如果你的芯片只支持 BLE 4.0,那就别想用这些新特性。

好了,这一章的内容就到这里。分层模型是理解 BLE 的基石,后面每一章都会用到这些概念。你先把这张图刻在脑子里,后面学起来会轻松很多。