01
引言
客户在使用 bluenrg-lp/lps 芯片时,增加 ota 服务后常常反馈说,编译代码区域超空间了,需要帮忙优化一下。后文主要通过下列步骤进行分析和优化 bluenrg-lp/lps 的代码空间:
a. 通过分析 bluenrg-lp/lps 的 ota 方式,让客户可以选择合适的方式;
b. 通过整体分析 bluenrg-lp/lps 的链接文件(*.icf/*.sct/*.ld)了解默认工程的存储分布;
c. 通过裁剪协议栈,选择合适的协议栈功能,优化 bluenrg-lp/lps 的代码空间;
d. 通过使用静态协议栈,进一步优化 bluenrg-lp/lps 的代码空间;
e. 其他方案;
总的来说通过两个维度来节省空间:一个是协议栈的裁剪维度:主要是通过修改宏配置实现编译对应应用需要的协议栈。另一个是 ota 和静态协议栈的维度:ota 和静态协议栈的选择流程图如下图所示
02
bluenrg-lp/bluenrg-lps的ota
2.1 ota 的框架
手机或者电脑做 gatt client,给带 ota 服务的设备升级。
2.2 官方提供的 ota 方式
默认提供的 ota 应用和协议栈编译在一个固件上。
a. 不带备份的(右图中的右半部分)
升级服务程序在 boot 端(ota service manager)。
省空间(存放了 2 份协议栈,1 份应用)
管理简单(只需管理一份应用)
b. 带备份的(右图中的左半部分)
升级服务程序在应用端
更消耗空间(存放了 2 份协议栈,2 份应用)
管理稍微麻烦(需要管理两份应用,lower 区域应用不能放置 higher 区域运行)
更安全
a. 不带备份的方式由以下组件构成:
ble_ota_servicemanager+ application
b. 带备份的由以下组件构成:
ble_ota_resetmanager +lower application (with ble ota service) orble_ota_resetmanager + higher application (with ble ota service)
对应在 sdk 中工程和配置如下图所示:
a.ble_ota_servicemanager 配合 ble_serialport 中的 sever_use_ota_servicemanager
b.ble_ota_resetmanger 配合 ble_serialport 中的 service_lowerapp_ota 或者service_lowerapp_ota 使用
2.3 使用带备份类型 ota 升级错误变砖头问题
编译器编译的 higher application 如果放置在 lower application 的位置,程序无法运行。app 程序可以知晓当前运行的固件是 lower 还是 higher app。可以在编译固件 higher application 和 lower application 中加入一些标记,用于给升级工具识别,当前需要下载的是higher application 还是 lower application 或者是否混用。建议每次发布时两个应用程序都编译生成,不要人为来管理固件,否则容易造成混乱,应该让升级 app 自动选择对应的来升级。
03
bluenrg-lp/lps的存储分析
3.1 linker 中宏定义作用范围
linker 中可定义一些宏、用于指定链接脚本文件所需的配置。这些宏定义不作用于.c文件或者.h文件,只作用于链接文件(.icf 或者.sct 或者 *.ld)。
3.2 链接脚本文件分析(代码区域)
不同的 ide 所使用的链接脚本文件的格式不同。比如,keil 使用“*.sct”文件,iar 使用“*.icf”文件,而 truestudio 使用 “*.ld”文件。
下面分析bluenrg-lp最新sdk中ble_serialport项目iar工程目录下的bluenrg_lp.icf文件, 其他ide一样,可以进行类比。由于flash的擦除必须是整页操作的,写flash之前必须将对应的页擦除,所以flash的划分需要2kb对齐。就算只使用到0.9kb,也需要划分2kb区域。
默认sdk中提供了4种程序的链接配置:
config_ota_higher
config_ota_lower
config_ota_use_service_manager
其他
对于这四种链接配置编译后,代码区域放置在如下地址。ble_ota_servicemanager 工程使用的是非 ota 程序,而 ble_serialport 中的 sever_use_ota_servicemanager 工程使用的是config_ota_use_service_manager。
上述4种程序的链接配置由以下宏定义来指定:memory_flash_app_size: 定义程序使用flash的大小。以工程ble_ota_servicemanager为例子,在linker中定义了memory_flash_app_size = 0x3000, 则表明ble_ota_servicemanager的大小不能超过0x3000(12*1024) 字节。ble_ota_servicemanager是一个带ota服务的启动程序,宏定义memory_flash_app_size限制这个工程编译的程序空间大小不能超过这个范围。
如果在linker中没有定义memory_flash_app_size,则对应的4种配置分别是:
memory_flash_app_offset: 定义程序编译链接地址的偏移(非ota程序)。如果在linker中没有定义memory_flash_app_offset,则对应的4种配置分别是:
前面提到默认sdk中提供了4种程序的链接配置,本质上只是计算memory_flash_app_offset和memory_flash_app_size的方式不同而已,如果应用需要,也可以改动这个链接脚本文件。
04
通过协议栈的初步裁剪与自定义优化空间
sdk 中默认提供了 4 种默认配置的协议栈加一种自定义的协议栈配置(ble_stack_custom_conf),如下图所示。
上述 5 种不同协议栈的配置,本质上就是通过使用宏控制不同的特性功能是否打开。只是前面 4种提供了默认便捷的设置,而最后一种可以进行细粒度更细的自定义的协议栈。
可以在 preprocesor symbols 中定义相关的宏来配置使用哪种协议栈配置。
如果选用细粒度更细的 ble_stack_custom_conf 协议栈配置,则在 其中在头文件“custom_ble_stack_config.h”中开关不同功能特性,大致占用的代码如下图所示。
05
协议栈的进一步裁剪:使用静态协议栈
5.1 静态协议栈工程的 4 种默认的配置
st 官方 sdk 中已经提供了静态协议栈的 demo,分为协议栈工程和应用工程两部分,路径为:c:usersuser namestbluenrg-lp dk 1.x.xprojectsble_examplesble_staticstack 静态协议栈工程默认提供了 4 种配置:
• release
• basic
• ota_btl_resetmanager
• ota_btl_resetmanager_basic
c:usersuser namestbluenrg-lp dk 1.x.0projectsble_examplesble_sensordemo_staticstack
• release
• lowerapp_ota
• higherapp_ota
那它们有什么区别呢?它们可以分为两组。
release 和 basic 是一组:它们运行时都是由协议栈程序直接跳转到一个固定的应用上;
release 和 basic 的区别:basic 的协议栈配置是 ble_stack_basic_conf, 而 release的协议栈配置是 ble_stack_full_conf。
不同的协议栈配置,包含的功能和占用的 flash 空间也不一致。
• 不同的协议栈配置包含的功能请查看 stack_user_cfg.h
• 占用的 flash 空间可以通过编译的 map 文件查看• 宏 reset_manager_size 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
• linker 中宏 memory_flash_app_size 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
ota_btl_resetmanager 和 ota_btl_resetmanager_basic 是另外一组:它们都是由协议栈程序跳转到 lower 应用程序或者 higher 应用程序;
• ota_btl_resetmanager 和 ota_btl_resetmanager_basic 的区别:ota_btl_resetmanager_basic 的协议栈配置是 ble_stack_basic_conf, 而ota_btl_resetmanager 的协议栈配置是 ble_stack_full_conf
• 不同的协议栈配置,包含的功能和占用的 flash 空间也不一致。
o 不同的协议栈配置包含的功能请查看 stack_user_cfg.h
o 占用的 flash 空间可以通过编译的 map 文件查看
o 宏 reset_manager_size 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
o linker 中宏 memory_flash_app_size 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
其中,一个工程负责生成协议栈,另一个工程负责应用,那么这里 ble_staticstack 中的release or basic 与 ota_btl_resetmanager or ota_btl_resetmanager_basic 怎么和release,lowerapp_ota 和 higherapp_ota 组合呢?
• ble_staticstack 中的 release or basic + ble_sensordemo_staticstack 中的release //不带备份 ota 的使用固定协议栈的方法
• ble_staticstack 中的 ota_btl_resetmanager or ota_btl_resetmanager_basic + ble_sensordemo_staticstack 中的 lowerapp_ota or higherapp_ota //带备份ota 的使用固定协议栈的方法
5.2 将工程实例化为静态协议栈工程编程基础
将工程实例化为静态协议栈涉及比较多的步骤,可以参考官方的文档 :bluenrg-lp_lps dk 1.2.0projectsble_examplesble_sensordemo_staticstackreadme.txt
以及 sdk 安装目录的 index.html 中的静态协议栈的介绍如下图所示。
如果在实例化 ota 程序时,可能需要修改链接脚本和 preprocesor symbols 中下面几个宏(具体不同应用,不同 ota 类型,具体需要定义的宏和宏的数值也不同):
reset_manager_sizeservice_manager_offsetservice_manager_sizememory_flash_app_sizememory_ram_app_offset
5.3 使用默认配置的协议栈
如果使用了 ota,发现空间不够,可以考虑将应用协议栈和 ota 协议栈合并使用如下图所示。
上图列举的是基于 bluenrg-lp 的默认提供的工程的大致数值(bluenrg-lps 类似,这里不再举例)。如果遇到不同的应用,可以实际裁剪协议栈适配不同的应用需求。
5.4 使用自定义配置的协议栈
使用静态协议栈可以实现更为精确的函数级别的裁剪:通过注释协议栈工程中的 bluenrg_lp_cmd_if.c 中的 cmd_call_table 中对应的函数,编译时可以将不使用的协议栈函数裁减出协议栈。
5.5 使用静态协议栈这种模式如何支持升级协议栈
当使用静态协议栈,默认协议栈就无法升级。为了能够支持协议栈也升级。需要增加一段 boot代码,当升级协议栈时,先放置在 app 区域,当升级完协议栈后,将 app 区域的协议栈拷贝到协议栈区域。接着继续升级被擦除的应用程序。boot 代码决定搬运协议栈和跳转到下一级。
06
优化后空间仍不足的其他方法
如果使用静态协议栈和空间仍然不足,可以考虑将一些常用而不需修改的通用模块编译进协议栈的工程。如果空间仍然差距比较远则考虑用片外 falsh 或者选用 stm32wb 系列,再或者使用 stm32+协处理器模式。
新日东升:应用于FPC生产的PTH系列产品,得到广泛供应商认可
渊亭科技宣布完成亿元人民币B轮融资
取暖器上架亚马逊有什么要求?
物联网技术主要作用是什么?
飞思卡尔城域小区基站处理器推动LTE架构迈向移动宽带时代
简谈BlueNRG-LP和-LPS的代码空间优化
人工智能扩展人类自身能力,发展应用中的安全风险及应对策略
什么是VDSL
当高等教育遇到人工智能会有什么样的效果
电解电容器的储运与焊接注意事项
几种白光LED驱动应用详解
O-RAN的参考架构及如何切分RAN
digilentFPGA开源创客开发板介绍
2010灯具行业发展水究竟有多深
TCL·XESS旋转智屏获ZOL权威大奖,产品优质实至名归
2018年会暨珠海集成电路产业创新发展高峰论坛成功召开,看中国区有哪些技术突破?
贴片功率电感厂商科普功率电感器参数及选型要求 gujing
TCL将于CES 2020上向外推出下一代Mini-LED技术
“用户体验年会 2023”在哈尔滨圆满召开
基于AT86RF230设计的2.4 GHz无线收发技术