3. 蓝牙核心规范与nRF54协议栈映射

在 nRF54 系列上开发 BLE 应用时,最容易混淆的不是 API 本身,而是“蓝牙核心规范里的概念”与“Nordic 协议栈里的实现对象”之间的对应关系。规范文档描述的是角色、过程和协议分层;SoftDevice Controller 与上层主机栈提供的是可调用的函数、事件和数据结构。只有把这两套语言对齐,才能在互操作与一致性测试中准确判断问题出在哪一层。

一、从规范分层到 nRF54 协议栈的纵向映射

蓝牙核心规范把 BLE 划分为 Controller 与 Host 两大部分。Controller 负责物理层、链路层以及部分低层控制;Host 负责 GAP、GATT、ATT、L2CAP、SM 等上层协议。nRF54 的软件架构与此对应:SoftDevice Controller(SDC)实现 Controller 侧功能,运行在专用或受控的无线资源上;Nordic 主机栈(如 nRF Connect SDK 中的 Bluetooth Host)实现 Host 侧协议。两者之间通过 HCI 命令、事件和数据包交互。

因此,当测试中出现“连接建立失败”“服务发现异常”“通知收不到”等现象时,第一步不是改应用代码,而是判断问题落在 Controller 还是 Host。例如链路层加密失败属于 Controller 与 SM 协作问题;而 GATT 特征值读取返回错误码,则更可能落在 ATT/GATT 层。

蓝牙核心规范 ↔ nRF54 协议栈纵向映射 Host 侧(Nordic Bluetooth Host / nRF Connect SDK) GAP 广播 / 扫描 / 连接建立 角色:Broadcaster / Observer GATT 服务 / 特征 / 描述符 Server / Client 角色 ATT 属性协议 / 句柄操作 Read / Write / Notify L2CAP 逻辑信道 / CID / MTU 固定信道 + 动态信道 SM(安全管理) 配对 / 绑定 / 加密 密钥分发 HCI 接口(命令 / 事件 / ACL 数据) Host 与 Controller 之间的标准边界 Controller 侧(SoftDevice Controller / SDC) Link Layer 广播 / 扫描 / 发起 / 连接 状态机与信道管理 LL Control 连接参数更新 / 加密控制 版本交换 / 特性交换 PHY 1M / 2M / Coded PHY 射频与调制 BLE 角色映射 Central / Peripheral → GAP 角色 + LL 连接状态 | Broadcaster / Observer → GAP 广播/扫描角色 Host 协议层 Controller 协议层

二、BLE 角色在 nRF54 上的落地方式

BLE 规范定义了四种 GAP 角色:Broadcaster、Observer、Central、Peripheral。在 nRF54 上,这些角色并不是四个独立开关,而是由广播、扫描、发起连接三类链路层行为组合而成。例如一个设备同时做广播和扫描,就同时具备 Broadcaster 与 Observer 能力;当它主动发起连接并成为连接发起方时,就进入 Central 角色。

实际开发中,角色选择直接影响 SoftDevice Controller 的资源分配。Central 角色需要维护连接状态机、连接参数和加密上下文;Peripheral 角色需要处理广播事件和连接请求。nRF54 的 SDC 支持多角色并发,但并发连接数、广播集数量和扫描窗口会共享射频资源。测试时如果发现连接间隔抖动或广播丢包,应检查是否超出了 SDC 配置的并发上限。

三、GAP 与 GATT 的职责边界

GAP 负责“如何找到对方并建立连接”,GATT 负责“连接建立后如何交换数据”。在 nRF54 主机栈中,GAP 相关操作通常通过 bt_le_adv_start()、bt_le_scan_start()、bt_conn_le_create() 等 API 完成;GATT 操作则通过 bt_gatt_discover()、bt_gatt_read()、bt_gatt_write()、bt_gatt_notify() 等 API 完成。

一个常见的互操作问题是:设备能连接,但服务发现失败。这通常不是 GAP 问题,而是 GATT/ATT 层问题。可能原因包括:服务 UUID 声明不完整、属性句柄范围错误、MTU 协商过小导致响应被截断。此时应先用抓包工具确认 ATT 层的 Read By Group Type 请求与响应是否匹配,再检查 GATT 数据库初始化代码。

四、L2CAP 与 ATT 的承载关系

ATT 并不是直接跑在链路层上的,它通过 L2CAP 的固定信道 CID 0x0004 传输。L2CAP 负责把上层数据分段、重组,并管理 MTU。nRF54 主机栈在连接建立后会进行 ATT MTU 交换,默认值通常为 23 字节,可协商到 247 字节甚至更大。MTU 越大,单次通知能携带的数据越多,但也会增加内存占用和分片风险。

在一致性测试中,L2CAP 层常见关注点包括:信令信道命令是否正确、MTU 交换是否在合理范围内、动态信道建立是否符合规范。如果测试仪报告“L2CAP 层拒绝”,应优先检查 SDC 的缓冲配置和主机栈的 L2CAP 信道注册逻辑。

五、SoftDevice Controller 的对应关系与配置要点

SoftDevice Controller 是 nRF54 上 Controller 侧的核心组件。它对外提供 HCI 接口,对内管理链路层状态机、射频调度和加密引擎。在 nRF Connect SDK 中,SDC 通常以预编译库形式集成,通过 sdc_hci_cmd_* 和 sdc_hci_event_* 接口与主机栈交互。

配置 SDC 时需要关注几个关键参数:

  • 并发连接数:决定 Central/Peripheral 可同时维持的连接数量,影响 RAM 占用。
  • 广播集数量:支持多广播集时,可同时发送不同广播数据,但会占用更多射频时间。
  • ATT MTU 上限:需与主机栈配置一致,否则协商结果可能被截断。
  • 数据长度扩展:启用后单包有效载荷可超过 27 字节,需与对端设备能力匹配。
在互操作测试中,建议先确认对端设备支持的蓝牙版本和可选特性(如 LE 2M PHY、LE Coded PHY、Data Length Extension),再调整 SDC 配置。盲目开启全部特性可能导致与旧设备连接不稳定。

六、映射关系速查与排障思路

把上述关系整理成一张对照表,便于在测试中快速定位:

规范概念 nRF54 实现对象 典型 API / 接口 常见测试关注点
GAP 广播 Host GAP + SDC Link Layer bt_le_adv_start() 广播间隔、广播数据格式
GAP 扫描 Host GAP + SDC Link Layer bt_le_scan_start() 扫描窗口、重复过滤
GATT 服务发现 Host GATT + ATT bt_gatt_discover() UUID 匹配、句柄范围
ATT 通知 Host ATT + L2CAP bt_gatt_notify() CCC 描述符、MTU 大小
L2CAP 信道 Host L2CAP + SDC CID 0x0004(ATT) MTU 交换、分段重组
链路层加密 SDC LL Control + SM HCI LE Start Encryption 密钥长度、加密模式

排障时可按“从下到上”的顺序检查:先确认 PHY 和链路层连接是否稳定,再检查 L2CAP 信道和 MTU,然后看 ATT 操作是否返回正确错误码,最后核对 GATT 数据库和 GAP 参数。这样能避免在应用层反复修改却找不到根因。

理解规范与协议栈的映射关系,本质上是在建立一套“分层定位”的思维:每一层都有明确的输入、输出和错误码,测试失败时先判断问题属于哪一层,再选择对应的工具和配置项。nRF54 的 SDC 与主机栈已经把这套分层结构实现得比较清晰,关键在于开发者是否愿意按层去读日志、抓包和验证。