扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

BlueNRG SDK 固件开发快速入门:从基础到实操指南

01/27 13:09
212
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

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 外设驱动层源码(如 GPIOUARTSPI 等) 底层驱动开发、硬件适配修改
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 升级、低功耗、安全加密等功能,部分关键例程特性如下:
BLE 例程名 核心特性 适用场景
BLE_SerialPort 主从一体、透传功能 蓝牙数据透传开发基础
BLE_Beacon 低功耗、协议栈占用小 信标类低功耗设备开发
BLE_SensorDemo 多传感器支持、OTA 升级、安全加密 物联网传感器数据采集与传输
BLE_MultipleConnections 多连接支持、低功耗 需同时连接多个设备的场景(如网关)
DTM 支持 ACI/HCI 指令 射频性能测试、协处理器模式开发

2. 快速固件开发:从例程到自定义功能实操

以 “BLE 从机 + 手机通讯 + 自定义控制” 为目标任务,演示基于 SDK 例程的快速开发流程,核心任务如下:
  1. BLE 从机配置:1 个服务 + 1 个支持 Write/Notify 属性的特征,广播名 “Hello”;
  2. 通讯功能:手机通过 STBLE Toolbox 与设备交互,打印收发数据;
  3. 自定义功能:LED 亮灭控制、1s 心跳包上传、按键事件通知。

第一步:工程选择与环境验证

(1)工程选型

选择BLE_SerialPort作为基础工程(支持 BLE 透传,可快速扩展自定义特征与功能),拷贝 SDK 目录下的DriversMiddlewaresProjects文件夹到用户工程目录(如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 的特征:
  1. 定义新特征 UUID
    #define RXTX_CHR_UUID 0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe1,0xf2,0x73,0xd9
    
  2. 配置特征属性(支持 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}
      }
    };
    
  3. 绑定服务与特征:将特征数量修改为 1,通过aci_gatt_srv_add_service函数将配置传递给协议栈,并获取特征句柄RXTXCharHandle

(2)广播名与设备名配置

  1. 修改广播名定义:
    #define LOCAL_NAME 'H','e','l','l','o'
    
  2. 同步设备名(确保广播名与 GAP 层设备名一致):
    uint8_t name[] = {'H','e','l','l','o'};
    ret = Gap_Profile_Set_Dev_Name(0, sizeof(name), name);
    
  3. 调整广播数据长度:根据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 为命令字,携带连接后秒计数值):
  1. 初始化定时器与回调函数:
    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); // 周期性启动
    }
    
  2. 在设备初始化函数中启动定时器:
    HAL_VTIMER_StartTimerMs(&second_timer, 1000);
    
  3. 心跳包发送逻辑(添加到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);
  }
}

功能验证

  1. 编译下载工程后,用 STBLE Toolbox 扫描设备,可见广播名 “Hello”;
  2. 连接设备并启用 Notify 订阅,手机将每秒接收 1 个 5 字节心跳包(以 0xaa 开头);
  3. 按下开发板按键,手机接收 0x03 命令字的按键事件;
  4. 手机发送 “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 开发核心优势

  1. 高效开发:丰富的例程可直接复用,无需从零搭建底层框架,大幅缩短开发周期;
  2. 灵活适配:支持 Keil、IAR、WiSE 等主流 IDE,兼容 BlueNRG-LP/LPS 全系列芯片;
  3. 功能全面:覆盖 BLE 主从、多连接、OTA 升级、低功耗、安全加密等核心场景;
  4. 文档完善:SDK 内置详细技术文档与示例,搭配 ST 官方工具(STBLE Toolbox、Navigator),降低调试难度。

相关推荐