1. BLE协议栈全景与开发环境搭建

1.1 协议栈分层结构

BLE协议栈由控制器(Controller)和主机(Host)两部分构成,分别对应物理层/链路层与上层应用功能。典型分层模型如下表:

层名英文职责
物理层PHY2.4GHz ISM频段射频收发,支持1M/2M/125kbps(LE Coded)
链路层LL广播、扫描、连接建立、数据包重传、加密状态机
主机控制接口HCIController与Host之间的命令/事件/数据通道(UART/SPI/USB)
逻辑链路控制与适配协议L2CAP协议多路复用、分段重组、MTU协商
安全管理SM配对、认证、密钥分发、加密
属性协议ATT客户端-服务器属性读写、通知、指示
通用属性配置文件GATT基于ATT的服务/特征/描述符定义
通用访问配置文件GAP广播模式、连接角色、设备发现
理解要点:应用开发者主要与GAP/GATT打交道,但广播工程直接涉及LL+GAP。底层HCI和L2CAP由SDK封装,调试时偶需关注MTU和连接间隔。
BLE协议栈分层架构 应用层 (App / Profile) GAP(通用访问配置文件) GATT(通用属性配置文件) SM(安全管理) ATT(属性协议) L2CAP(逻辑链路控制与适配协议) HCI(主机控制接口)—— 通信通道 链路层 (LL) — 广播/扫描/连接 物理层 (PHY) — 2.4GHz 调制解调 HOST CONTROLLER

1.2 开发板与SDK选择

主流BLE SoC及对应的SDK对比如下:

芯片厂商代表性型号SDK推荐工具链
NordicnRF52840 / nRF5340nRF5 SDK / nRF Connect SDK (Zephyr)SEGGER Embedded Studio / VS Code + nRF Command Line Tools
EspressifESP32-C3 / ESP32-S3ESP-IDF (BLE组件)VS Code + ESP-IDF插件
TICC2640R2 / CC2652SimpleLink CC13x2/CC26x2 SDKCCS / IAR
DialogDA1469xSmartSnippets SDKKeil / GCC
课程选型:优先使用Nordic nRF52840 DK + nRF5 SDK 17.1.0(原生BLE协议栈SoftDevice S140)作为主示例;同时提供ESP32-DevKitC + ESP-IDF v5.0备选方案。

1.3 开发环境搭建(Nordic nRF52840)

步骤一:安装工具链

  1. 下载安装SEGGER Embedded Studio(免费商用版本可用于nRF5 SDK)。
  2. 下载nRF Command Line Tools(含JLink驱动、mergehex、nrfjprog)。
  3. 安装GNU Arm Embedded Toolchain(版本 10.3-2021.10)。

步骤二:获取SDK和SoftDevice

# 下载 nRF5 SDK 17.1.0(约500MB)
wget https://www.nordicsemi.com/eng/nordic/downloads/.../nRF5_SDK_17.1.0_ddde560.zip
unzip nRF5_SDK_17.1.0_ddde560.zip -d ~/nRF5_SDK_17.1.0

# SDK内部包含SoftDevice hex文件
# 位置:components/softdevice/s140/hex/s140_nrf52_7.3.0_softdevice.hex

步骤三:第一个BLE广播工程(模板)

使用nRF5_SDK/examples/ble_peripheral/ble_app_beacon作为起点,修改main.c设定广播数据:

// main.c 核心片段
static void advertising_init(void)
{
    ret_code_t err_code;
    ble_advdata_t advdata;
    uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    // 构建广播数据(iBeacon示例)
    ble_advdata_manuf_data_t manuf_specific_data;
    manuf_specific_data.company_identifier = 0x004C; // Apple
    manuf_specific_data.data.p_data        = (uint8_t[]){0x02,0x15,0xE2,0x0A,0x39,0xF4,...};
    manuf_specific_data.data.size          = 25;

    memset(&advdata, 0, sizeof(advdata));
    advdata.name_type               = BLE_ADVDATA_NO_NAME;
    advdata.flags                   = flags;
    advdata.p_manuf_specific_data   = &manuf_specific_data;

    ble_gap_adv_params_t adv_params;
    memset(&adv_params, 0, sizeof(adv_params));
    adv_params.type        = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
    adv_params.p_peer_addr = NULL;   // 向所有设备广播
    adv_params.fp          = BLE_GAP_ADV_FP_ANY;
    adv_params.interval    = MSEC_TO_UNITS(100, UNIT_0_625_MS);
    adv_params.timeout     = 0;      // 持续广播

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &advdata, &adv_params);
    APP_ERROR_CHECK(err_code);
}
常见错误:SoftDevice未烧录时调用任何BLE API会返回NRF_ERROR_INVALID_STATE。务必先使用nrfjprog --program s140_nrf52_7.3.0_softdevice.hex --sectorerase写入SoftDevice。

1.4 ESP32-C3 备选环境配置

# 安装 ESP-IDF(推荐 v5.0 及以上)
git clone -b v5.0 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32c3
. ./export.sh

# 打开示例
cp -r examples/bluetooth/bluedroid/ble/ble_ibeacon ~/my_ble_beacon
cd ~/my_ble_beacon
idf.py set-target esp32c3
idf.py menuconfig  # 配置广播参数(UUID, Major, Minor)
idf.py build flash monitor

ESP32-C3使用Bluedroid协议栈(基于蓝牙双模规范),广播API在esp_ble_gap_config_adv_data()中设置。

1.5 调试与日志验证

nRF5调试:串口UART输出日志(波特率115200),Segger RTT可实时查看。典型广播启动日志:

00:00:00.000 <info> app: SoftDevice S140 7.3.0 initialized
00:00:00.100 <info> app: Starting advertising...
00:00:00.200 <info> app: Advertising interval = 100.00 ms
00:00:00.250 <info> app: Advertising started, handle 0x0001

ESP32调试:使用idf.py monitor查看蓝牙事件:

I (452) BT_INIT: BT controller initialized
I (462) BLE_IBEACON: Advertising data set successfully
I (472) BLE_IBEACON: Advertising started

1.6 性能调优建议

  • 广播间隔:100ms(10Hz)是功耗与发现速度的平衡点。间隔越小(20ms)温升越快,间隔越大(1s)省电但扫描端响应慢。
  • 广播通道:默认使用37/38/39三个通道。若需降低干扰,可强制使用单一通道(如只发CH37)。
  • 广播数据长度:最多31字节(传统广播)或255字节(扩展广播)。缩短数据可减少片上处理时间。
首次成功原则:先让LED闪烁工程跑通,再烧录SoftDevice,最后编译运行广播工程。分步验证可以快速定位环境问题。