BLE 协议栈架构与开发环境搭建

本章从 BLE 协议栈的层次结构出发,帮助读者建立对蓝牙低功耗通信模型的整体认知,并完成硬件选型、SDK 安装与工程模板解读。这是后续所有连接、数据读写和本地持久化实验的基础。

1.1 核心协议层:从物理射频到应用配置

BLE 协议栈从下到上可划分为四层:

  • 物理层(PHY):负责 2.4GHz 射频收发,支持 1Mbps、2Mbps 及 Coded PHY(125/500kbps)。
  • 链路层(LL):控制射频状态机(待机、广播、扫描、发起、连接),处理时序、重传与加密。
  • 主机协议栈(Host):包含 L2CAP(逻辑链路控制与适配协议)、ATT(属性协议)、GATT(通用属性配置文件)、GAP(通用访问配置文件)、SM(安全管理器)。
  • 应用层(App):用户代码通过 GATT/GAP API 实现具体业务逻辑。
核心概念:GAP 负责广播、扫描、连接的角色(Central/Peripheral);GATT 负责数据的组织与读写,通过 Service/Characteristic 树形结构暴露数据。
BLE 协议栈四层架构图 应用层(App) GATT / GAP API · 用户业务逻辑 · 任务调度 主机协议栈(Host Stack) GAP · GATT · ATT · L2CAP · SM 配置、安全、属性事务、逻辑信道复用 链路层(Link Layer) 状态机 · 时序 · 重传 · 加密引擎 物理层(PHY) 2.4GHz 射频 · 1M / 2M / Coded PHY 箭头方向:向下为数据流向

1.2 硬件选型:主流 BLE SoC 对比

选择 SoC 时需综合考虑功耗、RAM/Flash 大小、SDK 成熟度及社区资源。以下为三种常见平台:

参数Nordic nRF52840ESP32-C3TI CC2640R2F
内核Cortex-M4FRISC-V 单核Cortex-M3
Flash1 MB4 MB(外置)128 KB
RAM256 KB400 KB20 KB(缓存)+ 8 KB SRAM
BLE 版本5.45.05.0
SDK 工具链nRF5 SDK + SES / GCCESP-IDF + VSCodeCCS + TI BLE-Stack
典型应用穿戴、传感、MeshWiFi+BLE 混合、IoT低功耗传感、Beacon
硬件避坑:若需要同时使用 BLE 与 Flash 持久化,确保 SoC 具有足够 RAM 存放协议栈 + 应用数据 + 文件系统缓存。nRF52840 256KB RAM 通常够用,CC2640R2F 则需谨慎分配。

1.3 SDK 安装(以 nRF5 SDK v17.1.0 为例)

推荐使用 Segger Embedded Studio(SES)或 GCC + Makefile 进行编译。以下为基于 SES 的安装流程:

  1. 下载 nRF5 SDK 并解压至无空格路径。
  2. 下载并安装 SES(建议 v5.50 以上)。
  3. 打开 SDK 中的示例工程(如 examples/ble_peripheral/ble_app_uart)。
  4. 在 SES 中设置目标芯片(如 nRF52840_xxAA)。
  5. 编译并烧录。首次烧录需安装 J-Link 驱动。

SDK 关键路径结构:

nRF5_SDK_17.1.0_9b71d5c/
├── components/          # 驱动、协议栈、库
│   ├── ble/             # BLE 协议栈 API
│   ├── boards/          # 板级支持包
│   └── libraries/       # 通用库(FDS、FSTOR等)
├── examples/            # 示例工程
│   └── ble_peripheral/  # 外设示例
│       └── ble_app_uart/
├── external/            # 第三方(FreeRTOS、segger_rtt)
└── integration/         # 构建系统配置
性能优化要点:在工程中关闭不需要的协议栈特性(如 BLE Mesh、多连接)可减少 RAM 占用;使用静态内存分配替代动态 malloc 可避免堆碎片。

1.4 工程模板结构(以 nRF5 SDK 基础示例为例)

一个典型的 BLE 工程包含以下文件:

  • main.c:应用入口,初始化硬件、协议栈、定时器,进入主循环。
  • ble_.c/.h:自定义 GATT 服务实现。
  • app_scheduler.c(可选):任务调度器,用于非中断上下文事件处理。
  • sdk_config.h:协议栈和驱动的宏配置开关。
  • Makefile / SES project:编译与链接规则。

代码片段展示 BLE 初始化顺序(仅示意关键调用):

// 1. 初始化 SoftDevice(BLE 协议栈)
nrf_sdh_enable_request();
nrf_sdh_ble_enable(&ram_start);

// 2. 配置 GAP 参数
ble_gap_conn_params_t gap_conn_params = {
    .min_conn_interval = MSEC_TO_UNITS(20, UNIT_0_625_MS),
    .max_conn_interval = MSEC_TO_UNITS(20, UNIT_0_625_MS),
    .slave_latency     = 0,
    .conn_sup_timeout  = MSEC_TO_UNITS(4000, UNIT_10_MS)
};
sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN);
sd_ble_gap_conn_params_set(&gap_conn_params);

// 3. 添加 GATT 服务
ble_uart_service_init(&m_uart, uart_data_handler);
常见错误:
• 忘记调用 nrf_sdh_ble_enable() 导致协议栈未启动,连接失败。
• sdk_config.h 中协议栈 RAM 分配不足导致 HardFault。
• 硬件引脚定义与板级文件冲突,例如 PA08 被同时用于 UART RTS 和 GIPO 输出。