前言适用范围:BlueNRG-LP 软件, BlueNRG-1/2的也可以参考此方法 下文主要描述使用BlueNRG-LP SDK进行开发时,如何搭建使用静态协议栈环境。 如果你对BlueNRG-x系列的存储分布还不是那么熟悉,建议您阅读 BlueNRG系列存储分析(Flash_and_RAM)
BlueNRG-1/2使用静态协议栈参考Demo: https://github.com/wallekuang/BlueNRG-1-2_Static_Static BlueNRG-LP使用静态协议栈参考Demo: https://gitee.com/lucienkuang/BlueNRG-LP_Static_Stack.git 静态协议栈分多个工程,如果您只想简单使用,不做其他定制化的修改,并不想深入了解,可以直接复用上述给出的工程,然后只需要适配您自己的应用工程即可。 背景在使用BlueNRG-LP调试的时候,有时遇到Flash空间不够的问题,可能应用还需要包含OTA,可能OTA中又包含协议栈。为了解决Flash空间不够这个问题,推荐使用静态协议栈的方式,节省空间,加速OTA的升级过程。 知识背景须知下文描述具体的操作,默认您已经知晓ST 官方的BlueNRG-x 基本开发环境搭建和知晓OTA基本知识,ST官方提供比较多类型的OTA方式,详细请自行看官方文档 BLE Over Ther Air Firmware Upgrade (AN4869)或者Bluetooth LE Over Ther Air Firmware Upgrade (AN5463)。
温馨提示:请使用最新版本SDK进行开发
编译静态协议栈工程需要使用到GNU工具链,如果您没有安装,可以参考此文档进行安装 如何安装GNU工具链 参考使用官方静态协议栈Demo官方默认提供的静态协议栈工程的参考介绍: 静态协议栈工程的4种默认配置 参考使用已有的自定义配置静态协议栈工程。如果您对配置过程不感兴趣,或者觉得比较繁琐,可以直接使用ST官方SDK中已经提供了静态协议栈的Demo,或者使用这个 配置BlueNRG-LP工程为静态协议栈自定义配置静态协议栈1(OTA使用BLE_OTA_ServiceManager)如果你的应用工程移植起来不繁琐或者还没有开发应用并且ST官方SDK中已经提供了静态协议栈的Demo满足你的基本要求,你可以直接使用它。如果不是,那可能就需要直接在你目标的工程上改为静态协议栈,并且可能需要裁剪协议栈。下面我介绍一个比较常用用静态协议栈的修改方法。我们先通过了解Flash分布来知晓接下来这个实验的整个框架。应用程序APP这块,我们选择比较常用的BLE_SerialPort 工程;OTA 这里选择不备份的,单独的一个程序;协议栈选择Basic配置 Flash分布(此表格很重要,后续调试可以在此翻看):不同编辑工具,编译代码的效率不一样,个人实测,IAR的编辑的效率要比Keil 的高,有时有可能差别2KB以上。为了省事后续IAR 也采用和Keil 一致的参数。 - 后续调试IAR 平台和Keil 平台实际 Flash分布
Flash区域 占据空间 说明
NVM[0x1007F000,0x10080000)【127页~128页】[0x3F000,0x4000) 4KB=0x1000 ,协议栈存储GATT属性表和配对密钥等使用。
APP(BLE_SerialPort)[0x1005E000,0x1007F000)【60页~126页】[0x1E000,0x3F000) 客户应用程序(132KB=0x21000可用空间)
BLE_OTA_ServiceManager[0x1005B000,0x1005E000)【54页~59页】 [0x1B000,0x1E000) 应用OTA(12KB=0x3000)
BLE Stack(Basic)[0x10040000,0x1005B000) 【0页~53页】[0x00000,0x1B000) 协议栈(108KB=0x1B000,BLE_STACK_SLAVE_DLE_CONF, 并且使能CONTROLLER_MASTER_ENABLED),协议栈可以裁剪和增加.如果是只作为从机只需要0x18000(96KB)。
- BLE Stack 的工程使用的是Basic配置,但将宏配置为BLE_STACK_SLAVE_DLE_CONF,考虑到BLE_SerialPort工程中有Master部分的,我们这里代码中Mater部分的也编译进去,因此使能CONTROLLER_MASTER_ENABLED。(stack_user_cfg.h中BLE_STACK_SLAVE_DLE_CONF下使能 CONTROLLER_MASTER_ENABLED = 1)
- 这里协议栈的配置选择和配置比较简单,主要是使用了哪些功能就使能对应的宏。更多精细的协议栈优化可以到具体的函数,如果没有使用到,就将bluenrg_lp_cmd_if.c 中对应的函数注释,这里先不涉及复杂的操作。
- 配置好后编译生成固件, libbluenrg_lp_static_stack_basic.a,生成的固件将给BLE_OTA_ServiceManager工程和BLE_SerialPort工程使用。
- BLE_OTA_ServiceManager 的工程是BLE_OTA_ServiceManager ,主要实现不备份方式的OTA(即OTA服务程序和应用不捆绑在一起)
- APP 客户应用程序,这块可使用的大小可以根据实际使用BLE Stack size进行调整,后面会描述调整的方法
- 关于占据空间这块,第一部分是绝对地址,第二部分是Flash的页数,第三部分是相对地址。如果您对具体数值怎么得来有疑问,关于这点得通过下面的实操步骤往复调试,查看map,计算才能得来,这里是先给出结果。
我们将根据这个Flash的分布,从Flash的底部,往上一个一个工程调试配置, 即从 BLE Stack——》BLE_OTA_ServiceManager——》BLE_SerialPort 不同的应用工程配置,需要协议栈提供不同的特性支持,协议栈的配置和应用使用协议栈的配置需要保持一致。为了方便,这里BLE_SerialPort中做主机和从机的配置都选用同一种协议栈的配置,考虑到BLE_SerialPort中有做主机(CONTROLLER_MASTER_ENABLED),以及BLE_OTA_ServiceManager使用了CONFIG_SW_OTA_DATA_LENGTH_EXT特性,因此所有工程。 BLE Stack(Basic)工程的更改点如下:- 在工程配置Preprocessor中将RESET_MANAGER_SIZE=0x18000更改为:RESET_MANAGER_SIZE=0x1B000
- 因为更改了宏定义,使能了CONTROLLER_MASTER_ENABLED,需要占据更多的空间
- 在工程配置Preprocessor中将BLE_STACK_BASIC_CONF改为BLE_STACK_SLAVE_DLE_CONF
- 因为所有工程宏定义最好保持一致,只使用一个协议栈。
- 在工程配置Preprocessor中增加CONFIG_NUM_MAX_LINKS=1
- 这里需要根据实际应用来,如果此数值协议栈与其他工程不一致,有可能报RAM错误。
- 在工程配置Linker中将MEMORY_FLASH_APP_SIZE=0x18000更改为MEMORY_FLASH_APP_SIZE=0x1B000
- 需要更多的code区域,需要的大小可以通过生成的map文件查看得知。
- 在bluenrg_lp_cmd_if.c 中增加头文件包含 #include “stack_user_cfg.h” (如果没有包含该头文件的话)
如果您对MEMORY_FLASH_APP_SIZE,MEMORY_RAM_APP_OFFSET等链接脚本中的宏定义表示的意义不是那么清楚的话,建议您查看阅读BlueNRG系列存储分析(Flash_and_RAM) 配置BLE_OTA_ServiceManager为静态协议栈版本建议参考 BlueNRG-LP_DK_1_1_0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack\README.txt 为了不影响老的配置,这里新建一个配置 - IAR:Project——》Edit configurations. ---> 命名为StaticStackRlease
- Keil: File Extensions,Bolcks and Environment(Manage Project Items)
从工程文件中禁用libbluenrg_lp_stack.a 和stack_user_cfg.c . 在您的项目中包含 bluenrg_lp_stack_init_if.c 和 libbluenrg_lp_static_stack.a(来自 Middlewares\ST\Bluetooth_LE\Library\static_stack)。 其中Keil 平台添加.a文件需要如下图所示,手动选择文件为lib 文件。
禁用所有包含在静态堆栈中的外部模块和驱动程序(它们的 符号被导出并可被应用程序使用): - AES
- BLECNTR
- Cryptolib
- NVM
- PKA
- RNG
- GAP and GATT profiles
- HAL_VTimer
- rf_driver_hal_vtimer.c rf_driver_ll_radio_2g4.c rf_driver_ll_timer.c
根据 BlueNRG 静态堆栈映像占用的 Flash 大小为链接器定义 MEMORY_FLASH_APP_OFFSET。 例如。 如果静态堆栈映像使用 Flash 直到地址 0x1005 A8F0,则偏移量必须大于等于 0x1B000,这是与页面开头对齐的第一个可用 Flash 位置的偏移量。 为链接器定义 MEMORY_RAM_APP_OFFSET,以便在空闲 RAM 空间中分配变量,其中静态堆栈库没有分配其他变量。请参阅 BLE_SensorDemo_Static_Stack 项目中使用的 MEMORY_RAM_APP_OFFSET 以了解在使用静态堆栈时您的应用程序必须使用哪个 RAM 偏移 BlueNRG-LP DK 中包含的二进制文件。 // 总结Linker 中的宏定义 MEMORY_FLASH_APP_SIZE=0x3000 MEMORY_FLASH_APP_OFFSET=0x1B000 MEMORY_RAM_APP_OFFSET=0x06A0 Keil 中格式和IAR稍微有点不一样,根据葫芦画瓢可得 --predefine="-DMEMORY_FLASH_APP_SIZE=0x3000 -DMEMORY_FLASH_APP_OFFSET=0x1B000 -DMEMORY_RAM_APP_OFFSET=0x06A0"
使用与静态堆栈相同的模块化配置(例如,如果静态堆栈已使用 BLE_STACK_FULL_CONF 构建,则使用 BLE_STACK_FULL_CONF,如果静态堆栈已使用 BLE_STACK_BASIC_CONF 构建,则使用 BLE_STACK_BASIC_CONF)。 // 总结Preprocessor中的定义 SERVICE_MANAGER_OFFSET=0x1B000 SERVICE_MANAGER_SIZE=0x3000 BLE_STACK_SLAVE_DLE_CONF
#define SERVICE_MANAGER_OFFSET (0x0)#ifdef CONFIG_DEVICE_BLUENRG_LP #define SERVICE_MANAGER_SIZE PAGE_SIZE_ROUND(90* 1024) /* BlueNRG-LP, BLE stack v3.x with modular approach TBR*/#endif #define SM_APP_SIZE PAGE_SIZE_TRUNC((_MEMORY_FLASH_SIZE_-SERVICE_MANAGER_SIZE-NVM_SIZE))更改为:#ifndef SERVICE_MANAGER_OFFSET #define SERVICE_MANAGER_OFFSET (0)#endif#ifndef SERVICE_MANAGER_SIZE #define SERVICE_MANAGER_SIZE PAGE_SIZE_ROUND(90* 1024) /* BlueNRG-LP, BLE stack v3.x with modular approach TBR*/#endif #define SM_APP_SIZE PAGE_SIZE_TRUNC((_MEMORY_FLASH_SIZE_-SERVICE_MANAGER_SIZE-NVM_SIZE-SERVICE_MANAGER_OFFSET))- 修改完后,编译固件查看其地址,确认无误后下载运行,使用BLE测试工具测试(如果使用Keil工具,BLE_OTA_ServiceManager的偏移地址应该是0x1005B000)。
配置BLE_SerialPort为静态协议栈版本建议参考 BlueNRG-LP_DK_1_1_0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack\README.txt 这里举例子配置 Serial Port 的Service配置 为了不影响老的配置,这里新建一个配置 - IAR:Project——》Edit configurations. ---> 命名为StaticStackService
- Keil: File Extensions,Bolcks and Environment(Manage Project Items)
根据 BlueNRG 静态堆栈映像占用的 Flash 大小 ,加上BLE_OTA_ServiceManager区域所占的大小(12KB), 为链接器定义 MEMORY_FLASH_APP_OFFSET + BLE_OTA_ServiceManager size。 例如。 如果静态堆栈映像使用 Flash 直到地址 0x1005 9B20,则偏移量必须大于等于 0x1B000 + 0x3000,这是与页面开头对齐的第一个可用 Flash 位置的偏移量。 为Linker定义 MEMORY_RAM_APP_OFFSET,以便在空闲 RAM 空间中分配变量,其中静态堆栈库没有分配其他变量。请参阅 BLE_SensorDemo_Static_Stack 项目中使用的 MEMORY_RAM_APP_OFFSET 以了解在使用静态堆栈时您的应用程序必须使用哪个 RAM 偏移 BlueNRG-LP DK 中包含的二进制文件。 // 总结Linker 中的宏定义 CONFIG_OTA_USE_SERVICE_MANAGER=1 MEMORY_FLASH_APP_SIZE=0x21000 MEMORY_RAM_APP_OFFSET=0x06A0 MEMORY_FLASH_APP_OFFSET=0x1E000 Keil 中格式和IAR稍微有点不一样,根据葫芦画瓢可得 --predefine="-DCONFIG_OTA_USE_SERVICE_MANAGER=1 -DMEMORY_FLASH_APP_SIZE=0x21000 -DMEMORY_RAM_APP_OFFSET=0x06A0 -DMEMORY_FLASH_APP_OFFSET=0x1E000 "
增加 修改链接脚本文件: BlueNRG_LP.sct or BlueNRG_LP.icf // IAR左边 Keil 右边 主要增加“#Ifndef endif”
测试: - 检查是否通过编译
- 使用JFlash检查生成的Hex文件偏移地址
- 下载程序
- 检查串口日志和使用BLE 测试工具扫描广播
自定义配置静态协议栈2(OTA服务在应用BLE_SerialPort中,备份应用程序)Flash分布Flash区域 占据空间 说明
NVM[0x1007F000,0x10080000)【127页~128页】[0x3F000,0x4000) 4KB=0x1000 ,协议栈存储GATT属性表和配对密钥等使用。
HigherAPP(BLE_SerialPort)[0x1006D000,0x1007F000)【60页~126页】[0x2D000,0x3F000) 客户应用程序高地址区域(72KB=0x12000可用空间)
LowerAPP(BLE_SerialPort)[0x1005B000,0x1006D000)【60页~126页】[0x1B000,0x2D000) 客户应用程序低地址区域(72KB=0x12000可用空间)
BLE Stack(Basic)[0x10040000,0x1005B000) 【0页~53页】[0x00000,0x1B000) 协议栈(108KB=0x1B000,BLE_STACK_SLAVE_DLE_CONF, 并且使能CONTROLLER_MASTER_ENABLED),协议栈可以裁剪和增加.如果是只作为从机只需要0x18000(96KB)。
小结通过上述一步一步的优化,我们完成了将普通工程改成使用静态协议栈的方式,并且支持OTA。实际应用可能有各种不同的应用需求,用户可以根据同样原理去优化适配合适你们的工程。如果希望协议栈页可以通过空中升级,查看下文。进阶:配置支持协议栈的升级(待完善。。。)- 这里协议栈的升级由于空间不够,这里就采用2.4G 升级方式。工程路径: BlueNRG-LP DK 1.0.0\Projects\Peripheral_Examples\Examples_MIX\RADIO\RADIO_OTA_ResetManager-->Client
- 主要修改配置宏,前面描述比较详细,这里我就不一一描述了。主要罗列一些不同工程的linker配置和宏配置。
|