BlueNRG SDK 是意法半导体为 BlueNRG-LP/LPS 系列芯片打造的一站式固件开发平台,凭借丰富的例程、清晰的软件架构和灵活的配置能力,大幅降低蓝牙低功耗(BLE)及外设应用的开发门槛。本文基于 ST 官方 LAT1296 应用笔记(Rev 1.0),从 SDK 基础认知、快速开发实操到架构解析,系统梳理固件开发的核心流程,帮助工程师快速上手并实现自定义功能。
1. SDK 基础认知:目录结构与核心例程
1.1 目录结构解析
BlueNRG SDK 安装后包含 7 个核心目录,各目录功能明确,覆盖开发全流程需求:
| 目录名称 | 核心功能 | 典型使用场景 |
|---|---|---|
| Application | 含 PC 端辅助工具(BLUENRG-X_Wizard 协议栈配置、BlueNRG-LP_Navigator 一键烧录、Secure_Bootloader_GUI 安全启动) | 协议栈参数配置、固件烧录、安全启动配置 |
| Docs | 芯片硬件设计指南、协议规范、API 手册等全套资料 | PCB 设计前参考、开发过程中查阅技术细节 |
| Drivers | 外设驱动层源码(如 GPIO、UART、SPI 等) | 底层驱动开发、硬件适配修改 |
| Middlewares | 中间件源码(BLE 协议栈、AES 加密、HAL 库等) | 协议栈调用、中间件功能扩展 |
| Projects | 核心用户工程,含各类例程源码 | 基于例程二次开发、自定义功能实现 |
| Firmware | 预编译固件(.hex 格式) | 快速验证硬件功能、射频 / 功耗测试(如 Beacon 固件测功耗、DTM 固件测射频) |
| Utility | 工具箱(含 Keil pack 等 IDE 适配工具) | IDE 环境配置、开发工具补充 |
1.2 核心例程分类
SDK 的 Projects 目录包含三类核心例程,覆盖从基础外设到 BLE 应用的全场景需求:
- Periph_Examples:外设驱动例程(如 GPIO、定时器、ADC 等),适用于基础硬件功能开发;
- External_Micro:外部单片机例程,针对 BlueNRG 芯片作为协处理器的应用场景;
- BLE_Examples:蓝牙核心例程(最常用),支持从机 / 主机、OTA 升级、低功耗、安全加密等功能,部分关键例程特性如下:
2. 快速固件开发:从例程到自定义功能实操
以 “BLE 从机 + 手机通讯 + 自定义控制” 为目标任务,演示基于 SDK 例程的快速开发流程,核心任务如下:
- BLE 从机配置:1 个服务 + 1 个支持 Write/Notify 属性的特征,广播名 “Hello”;
- 通讯功能:手机通过 STBLE Toolbox 与设备交互,打印收发数据;
- 自定义功能:LED 亮灭控制、1s 心跳包上传、按键事件通知。
第一步:工程选择与环境验证
(1)工程选型
选择
BLE_SerialPort作为基础工程(支持 BLE 透传,可快速扩展自定义特征与功能),拷贝 SDK 目录下的Drivers、Middlewares、Projects文件夹到用户工程目录(如test_sdk1.3.0)。(2)环境配置与验证
- 打开
ProjectsBLE_SerialPort的 Keil/IAR 工程,勾选 “Browse Information”(启用函数跳转),选中 “Server” 工程配置; - 编译并下载到 STEVAL-IDB011V2 开发板,通过串口(波特率 115200、8N1)查看日志,确认工程正常运行;
- 用 STBLE Toolbox 扫描设备,应能搜索到广播名 “Sport_LP”,验证基础 BLE 功能正常。
第二步:BLE 从机核心配置
(1)特征与服务配置
原始工程含 TX/RX 两个独立特征,需合并为 1 个支持 Write/Notify 的特征:
- 定义新特征 UUID:
#define RXTX_CHR_UUID 0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe1,0xf2,0x73,0xd9 - 配置特征属性(支持 Notify/Write No Resp):
static const ble_gatt_chr_def_t serial_port_chars[] = { { .properties = BLE_GATT_SRV_CHAR_PROP_NOTIFY | BLE_GATT_SRV_CHAR_PROP_WRITE_NO_RESP, .permissions = BLE_GATT_SRV_PERM_NONE, .min_key_size = BLE_GATT_SRV_MAX_ENCRY_KEY_SIZE, .uuid = BLE_UUID_INIT_128(RXTX_CHR_UUID), .descrs = {.descrs_p = BLE_GATT_SRV_CCCD_DEF_NAME(tx), .descr_count = 1U} } }; - 绑定服务与特征:将特征数量修改为 1,通过
aci_gatt_srv_add_service函数将配置传递给协议栈,并获取特征句柄RXTXCharHandle。
(2)广播名与设备名配置
- 修改广播名定义:
#define LOCAL_NAME 'H','e','l','l','o' - 同步设备名(确保广播名与 GAP 层设备名一致):
uint8_t name[] = {'H','e','l','l','o'}; ret = Gap_Profile_Set_Dev_Name(0, sizeof(name), name); - 调整广播数据长度:根据
LOCAL_NAME长度更新广播包中 “Complete Local Name” 字段的长度参数。
第三步:通讯功能实现
(1)数据接收
找到
aci_gatt_srv_write_event回调函数(设备接收手机数据的入口),替换旧 RX 句柄为新特征句柄RXTXCharHandle,并添加数据打印:void aci_gatt_srv_write_event(uint16_t Connection_Handle, uint8_t Resp_Needed, uint16_t Attribute_Handle, uint16_t Data_Length, uint8_t Data[]) {
uint8_t att_error = BLE_ATT_ERR_NONE;
if (Attribute_Handle == RXTXCharHandle + 1) {
Data_Received(Data_Length, Data); // 自定义接收处理函数
att_error = BLE_ATT_ERR_NONE;
}
}
// 数据接收打印
void Data_Received(uint16_t length, uint8_t *data) {
printf("rn[TEST] Receive data:rn");
for (uint16_t i = 0U; i < length; i++) {
printf("%c", data[i]);
}
printf("rn");
}
(2)数据发送
取消原始工程的轮询发送逻辑,自定义 BLE 发送函数
user_send_data_over_ble,支持通过 Notify 发送数据:uint8_t user_send_data_over_ble(uint16_t handle, uint8_t *p_data, uint16_t data_len) {
uint8_t ret;
if (APP_FLAG(SEND_DATA) || APP_FLAG(TX_BUFFER_FULL)) return BLE_STATUS_BUSY;
if (data_len > (BLE_STACK_DEFAULT_ATT_MTU - 3)) return BLE_STATUS_INVALID_PARAMS;
ret = aci_gatt_srv_notify(connection_handle, handle + 1, 0, data_len, p_data);
if (ret == BLE_STATUS_SUCCESS) {
APP_FLAG_CLEAR(SEND_DATA);
printf("rn[TEST] Sent data:rn");
for (uint16_t i = 0U; i < data_len; i++) {
printf("%c", p_data[i]);
}
printf("rn");
} else if (ret == BLE_STATUS_INSUFFICIENT_RESOURCES) {
APP_FLAG_SET(TX_BUFFER_FULL);
}
return ret;
}
第四步:自定义功能实现
(1)LED 亮灭控制
在
Data_Received函数中添加 LED 命令处理逻辑,通过手机发送指定指令控制 LED:void user_led_process(uint8_t *p_data, uint16_t len) {
if (p_data[0] != 0x01) return; // 0x01为LED控制命令字
if (p_data[1] == 0x01) {
BSP_LED_On(BSP_LED1); // 点亮LED
} else if (p_data[1] == 0x00) {
BSP_LED_Off(BSP_LED1); // 熄灭LED
}
}
// 在Data_Received中调用
void Data_Received(uint16_t length, uint8_t *data) {
// 原有打印逻辑...
user_led_process(data, length);
}
(2)1s 心跳包上传
通过软件定时器实现每秒上传心跳包(以 0xaa 为命令字,携带连接后秒计数值):
- 初始化定时器与回调函数:
static BOOL timeout_flag = FALSE; VTIMER_HandleType second_timer; void user_second_timer_cb(void* param) { timeout_flag = TRUE; HAL_VTIMER_StartTimerMs(&second_timer, 1000); // 周期性启动 } - 在设备初始化函数中启动定时器:
HAL_VTIMER_StartTimerMs(&second_timer, 1000); - 心跳包发送逻辑(添加到
APP_Tick后台任务):void user_heartrate_process(BOOL init_flag) { static uint32_t count = 0; uint8_t send_buf[5]; if (init_flag) { count = 0; return; } send_buf[0] = 0xaa; // 心跳命令字 memcpy(&send_buf[1], (uint8_t*)&count, 4); // 秒计数值 user_send_data_over_ble(RXTXCharHandle, send_buf, 5); count++; } void APP_Tick(void) { if (APP_FLAG(CONNECTED) && timeout_flag) { timeout_flag = FALSE; if (APP_FLAG(NOTIFICATIONS_ENABLED)) { user_heartrate_process(FALSE); } else { user_heartrate_process(TRUE); } } }
(3)按键事件通知
在按键中断回调中添加 BLE 发送逻辑,按下按键时向手机发送事件:
void user_button_callback(void) {
printf("[TEST] Button pressedrn");
if (APP_FLAG(CONNECTED) && APP_FLAG(NOTIFICATIONS_ENABLED)) {
user_send_data_over_ble(RXTXCharHandle, (uint8_t*)"x03", 1); // 0x03为按键事件命令字
}
}
// 按键中断服务函数中调用
void GPIOA_IRQHandler(void) {
if (BSP_PB_GetITPendingBit(BSP_PUSH1)) {
user_button_callback();
BSP_PB_ClearITPendingBit(BSP_PUSH1);
}
}
功能验证
- 编译下载工程后,用 STBLE Toolbox 扫描设备,可见广播名 “Hello”;
- 连接设备并启用 Notify 订阅,手机将每秒接收 1 个 5 字节心跳包(以 0xaa 开头);
- 按下开发板按键,手机接收 0x03 命令字的按键事件;
- 手机发送 “0x01 0x01” 指令点亮 LED,发送 “0x01 0x00” 指令熄灭 LED,串口打印收发数据。
3. BlueNRG SDK 软件架构解析
3.1 三层软件架构
SDK 采用 STM32 典型的三层架构,分层清晰、低耦合,便于开发与维护:
- 驱动层(Driver):底层硬件驱动(外设、射频),提供标准化接口;
- 中间件层(Middleware):BLE 协议栈、加密库、HAL 库等,封装核心功能;
- 用户层(User):应用逻辑实现,核心文件包括
serial_port.c(应用逻辑)、BLE_SerialPort_main.c(程序入口与主流程)、gatt_db.c(GATT 服务 / 特征配置)、rf_device_it.c(中断服务函数)。
3.2 前后台系统流程
SDK 例程默认采用 “前后台” 裸机架构,兼顾简单性与实用性:
- 前台处理:中断驱动(如按键中断、BLE 事件中断),负责置位状态标志位(如连接标志、数据接收标志);
- 后台处理:
main函数的while(1)循环,运行 BLE 协议栈、APP_Tick任务调度、用户逻辑处理等; - 核心优势:无需复杂的操作系统配置,开发门槛低,适合中小型应用场景;若需复杂功能,可在此基础上添加调度器扩展。
4. BlueNRG SDK 开发核心优势
- 高效开发:丰富的例程可直接复用,无需从零搭建底层框架,大幅缩短开发周期;
- 灵活适配:支持 Keil、IAR、WiSE 等主流 IDE,兼容 BlueNRG-LP/LPS 全系列芯片;
- 功能全面:覆盖 BLE 主从、多连接、OTA 升级、低功耗、安全加密等核心场景;
- 文档完善:SDK 内置详细技术文档与示例,搭配 ST 官方工具(STBLE Toolbox、Navigator),降低调试难度。
阅读全文
212