2. BLE协议栈架构:协议栈分层模型、Controller层、Host层、Application层、各层职责

做嵌入式通信开发,尤其是搞蓝牙低功耗,第一件事就是得把协议栈的架构搞清楚。我见过太多新手一上来就调API,结果遇到连接断连、数据丢包、功耗下不来,完全不知道问题出在哪一层。

说白了,BLE协议栈就是一套分层的软件体系。每一层只管自己的事,层与层之间通过标准接口通信。这种设计的好处很明显——你换芯片、换协议栈版本,只要接口不变,上层代码基本不用动。

核心观点:BLE协议栈分为三大层——Controller层、Host层、Application层。Controller管物理收发,Host管逻辑控制,Application管业务逻辑。

2.1 分层模型总览

先看一张整体架构图,我习惯把它记成「下中上」三层结构。底层是Controller,中间是Host,顶层是Application。每一层内部又细分了几个子层。

BLE协议栈分层架构图 BLE协议栈分层模型 Application层 用户应用逻辑 / 配置文件 / 业务数据处理 Host层 GATT (Generic Attribute Profile) ATT (Attribute Protocol) L2CAP (Logical Link Control and Adaptation Protocol) Controller层 LL (Link Layer) PHY (Physical Layer) HCI (Host Controller Interface) 是Host与Controller之间的通信桥梁

嗯,这张图我建议你多看两眼。每一层都有自己明确的边界,这也是BLE能保持低功耗、低成本、高可靠性的关键原因。

2.2 Controller层——管好物理世界

Controller层是离硬件最近的一层。它直接操作射频收发器,负责把数据变成无线电波发出去,也负责把收到的无线电波还原成数据。

Controller层内部又分两个子层:

  • PHY(物理层):定义无线信号的调制方式、频率、功率。BLE工作在2.4GHz ISM频段,有40个信道,每个信道2MHz带宽。PHY决定了你能传多远、功耗多少。
  • LL(链路层):这是Controller的核心。它管理设备状态——待机、广播、扫描、发起连接、已连接。还负责数据包的组装、拆解、重传、加密。

我的经验:有一次客户反馈设备连接距离只有5米,怎么调天线都没用。后来发现是LL层配置了过短的连接间隔,导致接收窗口太小。把连接间隔从7.5ms调到15ms,距离直接翻倍。你看,问题往往不在硬件,在协议栈配置。

2.3 Host层——管好逻辑与数据

Host层在Controller之上,它不关心无线电怎么收发,只关心数据怎么组织、怎么交互。Host层内部有三个关键子层:

2.3.1 L2CAP

L2CAP是逻辑链路控制和适配协议。它干两件事:

  • 复用:把上层多个协议(ATT、SMP等)的数据流合并到一条物理链路上。
  • 分段重组:上层数据包太大?L2CAP帮你切小。收到小包?帮你拼回去。

2.3.2 ATT

属性协议。BLE里所有数据都以「属性」的形式存在。一个属性就是一个数据单元,包含句柄、UUID、权限、值。ATT定义了六种操作——读、写、通知、指示、广播、发现。

2.3.3 GATT

通用属性配置文件。它基于ATT,定义了更高级的数据交互模型。比如Service、Characteristic、Descriptor这些概念,都是GATT层引入的。

关键区别:ATT管的是「怎么读写数据」,GATT管的是「数据长什么样、怎么组织」。你写应用代码时接触最多的就是GATT层。

2.4 Application层——管好业务

Application层就是你的代码所在的地方。它调用GATT API,定义自己的Service和Characteristic,处理业务逻辑。

举个例子,你做一个温度传感器:

  • Application层定义了一个「温度Service」,里面包含一个「温度值Characteristic」。
  • 当传感器采集到新温度,Application层调用GATT的Notify接口,把数据发出去。
  • 手机端收到通知,解析出温度值,显示在App上。

Application层不关心底层是哪个芯片、射频怎么配置、数据包怎么重传。它只关心业务。

2.5 HCI——连接Host与Controller的桥梁

HCI(Host Controller Interface)不是独立的一层,它是Host和Controller之间的通信接口。在单芯片方案里,HCI是内部函数调用;在双芯片方案里(比如Host跑在MCU上,Controller跑在蓝牙芯片上),HCI走UART、SPI或USB。

特性 单芯片方案 双芯片方案
HCI实现方式 内部函数调用 UART/SPI/USB
延迟 低(微秒级) 较高(毫秒级)
功耗 更低 略高(额外通信开销)
灵活性 低(芯片绑定) 高(可更换Host或Controller)
典型场景 低功耗传感器、穿戴设备 网关、手机、复杂嵌入式系统

我曾经踩过的坑:双芯片方案里,HCI的UART波特率设置不对,导致Host发命令给Controller时偶尔丢包。设备连接成功率从99%掉到70%。排查了三天,最后发现是波特率不匹配。所以,HCI通信参数一定要在初始化阶段做握手校验,别想当然。

2.6 各层职责速查表

为了方便你快速回顾,我整理了一张职责清单:

层级 子层/模块 核心职责
Controller PHY 射频收发、调制解调、信道选择
LL 设备状态管理、数据包收发、重传、加密
Host L2CAP 协议复用、数据分段重组
ATT 属性读写操作、数据交互
GATT 数据模型定义(Service/Characteristic)
Application 用户代码 业务逻辑、数据处理、用户交互

2.7 数据流在协议栈中的旅程

你想想看,一个温度值从传感器到手机App,在协议栈里是怎么走的?

  1. Application层:采集温度,调用GATT的Notify接口,把温度值传给GATT。
  2. GATT层:把温度值封装成Attribute PDU,加上句柄和UUID,传给ATT。
  3. ATT层:生成ATT协议数据单元,传给L2CAP。
  4. L2CAP层:加上L2CAP头(包含通道ID),如果数据太大就分段,传给HCI。
  5. HCI:封装成HCI数据包,通过UART/SPI传给Controller。
  6. LL层:拆开HCI包,组装成Link Layer数据包,加上接入地址、CRC等,传给PHY。
  7. PHY层:调制成射频信号,在2.4GHz信道上发出去。

接收端反过来走一遍。每一层只处理自己该处理的部分,不越界。这就是分层设计的美妙之处。

我个人习惯:调试BLE问题时,先确定问题出在哪一层。如果是连不上,查Controller层;如果是数据读不到,查Host层;如果是业务逻辑不对,查Application层。分层排查,效率最高。

好了,这一章的内容就这些。协议栈的分层模型是后续所有章节的基础,你把它吃透了,后面讲连接、广播、配对、功耗优化,都会轻松很多。