你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的BlueNRG-LP 和-LPS 的代码空间优化经验分享

[复制链接]
攻城狮Melo 发布时间:2023-11-16 19:19
01引言
6 m; I5 ^. `" U0 f客户在使用 BlueNRG-LP/LPS 芯片时,增加 OTA 服务后常常反馈说,编译代码区域超空间了,需要帮忙优化一下。后文主要通过下列步骤进行分析和优化 BlueNRG-LP/LPS 的代码空间:
, P6 \$ J8 C0 i0 E! d+ Aa. 通过分析 BlueNRG-LP/LPS 的 OTA 方式,让客户可以选择合适的方式;. q! u+ n# a! h1 v3 ?
b. 通过整体分析 BlueNRG-LP/LPS 的链接文件(*.icf/*.sct/*.ld)了解默认工程的存储分布;2 D; W8 Z& L! r" w: W6 w" R8 M
c. 通过裁剪协议栈,选择合适的协议栈功能,优化 BlueNRG-LP/LPS 的代码空间;
7 a+ d* B- s9 s0 y+ ~; L6 _d. 通过使用静态协议栈,进一步优化 BlueNRG-LP/LPS 的代码空间;0 T" O* D* D9 @' f
e. 其他方案;
% P" W1 |! s/ b4 }
9 T9 ^; g2 k3 ~! F: T8 f
微信图片_20231116191908.jpg 5 P9 m% N* M* P$ a) ~( J% l/ C

% h: k3 ~0 w( ^* `& K总的来说通过两个维度来节省空间:一个是协议栈的裁剪维度:主要是通过修改宏配置实现编译对应应用需要的协议栈。另一个是 OTA 和静态协议栈的维度:OTA 和静态协议栈的选择流程图如下图所示8 R2 f  v( c6 L0 O* g: O

* |  w0 q+ l0 }, p
02BlueNRG-LP/BlueNRG-LPS的OTA
' C4 @9 l5 R  D1 e% k, u  W2.1 OTA 的框架4 ^/ l4 [8 k3 Z1 F3 y+ j3 V3 [
手机或者电脑做 GATT Client,给带 OTA 服务的设备升级。) q' [) }/ H: l
" i- U( v- d% t4 `, R
微信图片_20231116191905.jpg
0 D( |7 h% ]' P' l. \* Y
# S* A$ G/ x. i7 {/ l
2.2 官方提供的 OTA 方式' W" U3 X7 e! A* |
默认提供的 OTA 应用和协议栈编译在一个固件上。, |2 Z) `% x' D4 o& b1 ?
a. 不带备份的(右图中的右半部分)3 y3 l, e3 |1 v5 x/ ~
升级服务程序在 Boot 端(OTA Service manager)。
0 J$ Q) n. M. ^/ `7 {" c省空间(存放了 2 份协议栈,1 份应用)# ~) E7 J0 X0 B5 g+ o- E) B
管理简单(只需管理一份应用)
/ }; X' D" A2 ]0 Lb. 带备份的(右图中的左半部分)* j1 d7 a' s- |; `9 s- V
升级服务程序在应用端
0 t, `, v: F1 Z+ ?5 Q6 [' q更消耗空间(存放了 2 份协议栈,2 份应用)
! K7 C1 `% i$ |8 e管理稍微麻烦(需要管理两份应用,Lower 区域应用不能放置 Higher 区域运行)0 `5 p3 d: u4 |' |- q' f4 p2 @' _
更安全
- F+ \- S* Q+ v& M% ^" y; M6 H* E3 Z+ V* f
微信图片_20231116191901.jpg
6 ~0 B* h% o/ `/ ^7 O9 i( c+ H. ?" K! Z
2 B. q- O7 T2 P1 fa. 不带备份的方式由以下组件构成:( [( V/ }8 k9 z. V  K; }8 G( t
BLE_OTA_ServiceManager+ application0 ?4 {% i; l4 H1 Y' B5 R- ]$ H
b. 带备份的由以下组件构成:
0 v- N9 |& }/ F2 h& DBLE_OTA_ResetManager +Lower Application (with BLE OTA service) orBLE_OTA_ResetManager + Higher Application (with BLE OTA service)9 D+ Z2 [/ y7 {3 W
: d' A: c) \" T+ X2 f
对应在 SDK 中工程和配置如下图所示:  m8 D4 k$ q' i4 E0 R5 J
a.BLE_OTA_ServiceManager 配合 BLE_SerialPort 中的 Sever_Use_OTA_serviceManager
5 k- x5 R) e( R  E4 b" u; r9 Fb.BLE_OTA_ResetManger 配合 BLE_SerialPort 中的 Service_LowerApp_OTA 或者Service_LowerApp_OTA 使用$ D. k/ ~* \% w* q5 b2 t- T6 L" O

! |4 D3 v+ S3 Z# @9 F3 v: j
微信图片_20231116191859.jpg
( \5 C! _5 S3 u2 h) A' F, g1 @0 t

- p8 K$ L/ K7 q# X: B! ~2.3 使用带备份类型 OTA 升级错误变砖头问题
" R0 _/ P  T) I0 K  z. D" c. g# d编译器编译的 Higher Application 如果放置在 Lower Application 的位置,程序无法运行。APP 程序可以知晓当前运行的固件是 Lower 还是 Higher APP。可以在编译固件 Higher Application 和 Lower Application 中加入一些标记,用于给升级工具识别,当前需要下载的是Higher Application 还是 Lower Application 或者是否混用。建议每次发布时两个应用程序都编译生成,不要人为来管理固件,否则容易造成混乱,应该让升级 app 自动选择对应的来升级。
- {% j  B$ e# ?5 b4 a+ W' J( e. {% r' y) {! @: {
; o$ W5 U3 u+ B; v9 Y
微信图片_20231116191855.jpg
5 F8 p! u7 L' S. Q
; N2 [2 F: V; L- @+ r% p$ k2 X
- s. v+ S$ F1 w: v
03BlueNRG-LP/LPS的存储分析
' E0 }  m3 I/ f; v" n! Q! r3.1 linker 中宏定义作用范围% |7 O/ A/ x8 `  t  [+ S; x
Linker 中可定义一些宏、用于指定链接脚本文件所需的配置。这些宏定义不作用于.c文件或者.h文件,只作用于链接文件(.icf 或者.sct 或者 *.ld)。6 h* H" y* M7 N# K

  G. z. g2 X3 C; P
* }5 S7 _8 ]3 [* U( h6 _) s2 f' q
3.2 链接脚本文件分析(代码区域)4 x4 B# j8 }8 R9 z
不同的 IDE 所使用的链接脚本文件的格式不同。比如,Keil 使用“*.sct”文件,IAR 使用“*.icf”文件,而 TrueStudio 使用 “*.ld”文件。
9 X! {" e" U  z6 v+ c  C
" V* c. o& a0 o$ \2 |, e下面分析BlueNRG-LP最新SDK中BLE_SerialPort项目IAR工程目录下的BlueNRG_LP.icf文件, 其他IDE一样,可以进行类比。由于Flash的擦除必须是整页操作的,写Flash之前必须将对应的页擦除,所以Flash的划分需要2KB对齐。就算只使用到0.9KB,也需要划分2KB区域。% d$ T1 E6 M. J6 [; P/ T" s

+ n( p& n0 _% A5 |默认SDK中提供了4种程序的链接配置:  k* z* Q/ @% \( m
1.CONFIG_OTA_HIGHER
% j+ g, E+ U! ?% ]- q" R' s2.CONFIG_OTA_LOWER
& {, `$ |9 |6 @# I5 O) o# }$ Q3.CONFIG_OTA_USE_SERVICE_MANAGER
4 U, }( R+ L! N$ m) Q4.其他
- o- j4 }6 w/ [5 [0 U( |
5 c& o; ~4 |3 Y4 A
微信图片_20231116191852.jpg
# X# x( t8 ?2 T2 i6 T" h
; w% _9 I, F3 ?6 [1 F
对于这四种链接配置编译后,代码区域放置在如下地址。BLE_OTA_ServiceManager 工程使用的是非 OTA 程序,而 BLE_SerialPort 中的 Sever_Use_OTA_serviceManager 工程使用的是CONFIG_OTA_USE_SERVICE_MANAGER。3 p# x5 w+ G1 i

: U. S* m1 i. r
微信图片_20231116191849.jpg : ~/ i8 j* t- r% g: m9 c
% w% X4 P: }& M" Z9 n0 T
上述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限制这个工程编译的程序空间大小不能超过这个范围。: x- [# D5 z2 K# p
) y) N; _' T( I- Z8 J9 s2 j- W
如果在linker中没有定义MEMORY_FLASH_APP_SIZE,则对应的4种配置分别是:
) N* O0 b4 {; _, u* S
* {# H/ g+ z* @( a- L, b0 r! ^
微信图片_20231116191846.jpg ! Q7 `, X. o6 \" C

( ^  R/ {" G* a* W( lMEMORY_FLASH_APP_OFFSET: 定义程序编译链接地址的偏移(非OTA程序)。如果在linker中没有定义MEMORY_FLASH_APP_OFFSET,则对应的4种配置分别是:
* i( m* F$ v! ^  H% Y
# {! o( }# X; T2 E; W1 D: M; U" n
微信图片_20231116191843.jpg
0 v3 m) p/ M' R3 J
$ @! J, e9 F1 J前面提到默认SDK中提供了4种程序的链接配置,本质上只是计算MEMORY_FLASH_APP_OFFSET和MEMORY_FLASH_APP_SIZE的方式不同而已,如果应用需要,也可以改动这个链接脚本文件。4 A) c2 @* U5 m, r/ |  w
: n$ ^; [6 |4 {% d3 n* T2 x# Q
1 ^& M, ^. A! {/ V
04通过协议栈的初步裁剪与自定义优化空间
3 N- ]/ G3 I: ]+ _6 J  f# S& I! c& XSDK 中默认提供了 4 种默认配置的协议栈加一种自定义的协议栈配置(BLE_STACK_CUSTOM_CONF),如下图所示。
) C0 ]+ O  N/ z; n' e7 K" ~/ a( S( {. H- F3 _2 O! F
微信图片_20231116191839.jpg
3 C$ Y, a! v. ^, Y" w8 u8 y9 S

/ h4 D6 u) K! h/ f/ K上述 5 种不同协议栈的配置,本质上就是通过使用宏控制不同的特性功能是否打开。只是前面 4种提供了默认便捷的设置,而最后一种可以进行细粒度更细的自定义的协议栈。
. b3 D2 t0 Z# U5 b
+ k  W  W6 o$ w! Y/ D) g- i/ ?可以在 Preprocesor Symbols 中定义相关的宏来配置使用哪种协议栈配置。
, J6 e  z% {! l! W, A8 ?  ^
3 D( C. a5 p# b/ G
微信图片_20231116191836.jpg " a2 \* n1 }( k: M6 M6 R! |$ V

. L9 @; S: Z- f' R+ l9 e如果选用细粒度更细的 BLE_STACK_CUSTOM_CONF 协议栈配置,则在 其中在头文件“custom_ble_stack_config.h”中开关不同功能特性,大致占用的代码如下图所示。& s9 B) f& U5 a7 D5 b  t: D& g
8 x9 ]- A3 m8 z6 N* e
微信图片_20231116191833.jpg
, y" [0 k# I4 V, H5 o: F4 @- L6 E4 e8 `! t* \
- K1 u% a+ P1 ]% e( g9 }
05协议栈的进一步裁剪:使用静态协议栈
& _/ V2 h' Y0 b: A( @/ r1 s: j  y" [' a5.1 静态协议栈工程的 4 种默认的配置" u+ E# G! X- d! M3 K) ^  T8 [' D1 m
ST 官方 SDK 中已经提供了静态协议栈的 Demo,分为协议栈工程和应用工程两部分,路径为:C:\Users\user name\ST\BlueNRG-LP DK 1.x.x\Projects\BLE_Examples\BLE_StaticStack 静态协议栈工程默认提供了 4 种配置:
+ j( Z' j* e0 O2 _! J4 R, [• Release9 _" @& s) b& ?
• Basic
7 |9 Y' }/ j! h3 b2 r' M- p- [• OTA_BTL_ResetManager$ `2 l/ X7 C. H3 X- H
• OTA_BTL_ResetManager_Basic
2 [" q1 E. M' p- R$ n/ G6 }# n

% Y% {+ Z" ], I+ ~/ kC:\Users\user name\ST\BlueNRG-LP DK 1.x.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack* M" _' z) C# o. R; i. X9 T
• Release) M6 `. n0 z/ S
• LowerApp_OTA+ t. p' l- K0 L. m/ i+ O: E6 Y
• HigherApp_OTA6 Y3 W0 I8 G% Y# d7 B4 k+ m. ^

  |/ b' O4 G$ F
微信图片_20231116191830.jpg 7 Q; P' M& l: [$ F7 F) U
4 f9 G2 e5 N4 l- j+ V
那它们有什么区别呢?它们可以分为两组。" H  \/ v/ q. K7 h( B
  B% O3 {1 J9 T) K8 r0 T
Release 和 Basic 是一组:它们运行时都是由协议栈程序直接跳转到一个固定的应用上;$ y- o" l8 n- s2 o8 g* m

" ~% t' X% r( c8 C7 G; _
Release 和 Basic 的区别:Basic 的协议栈配置是 BLE_STACK_BASIC_CONF, 而 Release的协议栈配置是 BLE_STACK_FULL_CONF。
$ G6 U; M9 a3 a  N7 N

  ?; `$ _! w1 Y7 W6 W不同的协议栈配置,包含的功能和占用的 Flash 空间也不一致。- @% Z  I' T; d& s( S' }0 Q0 D
• 不同的协议栈配置包含的功能请查看 stack_user_cfg.h
* u; E: V# C3 z+ J! O6 Z! `( U) Q2 f• 占用的 Flash 空间可以通过编译的 Map 文件查看• 宏 RESET_MANAGER_SIZE 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。5 ~) c; {5 A. o- R6 [: v
• Linker 中宏 MEMORY_FLASH_APP_SIZE 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
3 h# p' H) I2 s, Z2 E+ t7 L' A2 Q' i4 z+ t
OTA_BTL_ResetManager 和 OTA_BTL_ResetManager_Basic 是另外一组:它们都是由协议栈程序跳转到 Lower 应用程序或者 Higher 应用程序; 6 M4 b/ z4 Q) ?

7 Z+ {! ^3 x  D) b$ J; W' k• OTA_BTL_ResetManager 和 OTA_BTL_ResetManager_Basic 的区别:OTA_BTL_ResetManager_Basic 的协议栈配置是 BLE_STACK_BASIC_CONF, 而OTA_BTL_ResetManager 的协议栈配置是 BLE_STACK_FULL_CONF
) f) K9 H8 [4 h2 @( W2 Z+ q, ?" J
• 不同的协议栈配置,包含的功能和占用的 Flash 空间也不一致。
) i, u" D  Z$ L" x" ]7 uo 不同的协议栈配置包含的功能请查看 stack_user_cfg.h' T9 ^0 x5 g& S! X8 I  T8 r! Z) A
o 占用的 Flash 空间可以通过编译的 Map 文件查看6 _. w( O0 ^- [" h; _
o 宏 RESET_MANAGER_SIZE 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
+ \2 ^; v7 \. V9 Zo Linker 中宏 MEMORY_FLASH_APP_SIZE 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。 7 B! z$ Q: {( l3 J+ K' B9 o

& ~2 ~8 U. z2 K+ L" Z+ a) i- K其中,一个工程负责生成协议栈,另一个工程负责应用,那么这里 BLE_StaticStack 中的Release or Basic 与 OTA_BTL_ResetManager or OTA_BTL_ResetManager_Basic 怎么和Release,LowerApp_OTA 和 HigherApp_OTA 组合呢?! |& }0 Q- a) p0 w
• BLE_StaticStack 中的 Release or Basic + BLE_SensorDemo_StaticStack 中的Release //不带备份 OTA 的使用固定协议栈的方法
: \  y6 ?5 f; `2 F& {( J• BLE_StaticStack 中的 OTA_BTL_ResetManager or OTA_BTL_ResetManager_Basic + BLE_SensorDemo_StaticStack 中的 LowerApp_OTA or HigherApp_OTA //带备份OTA 的使用固定协议栈的方法+ _2 t% V# S/ O4 d1 ~+ B& Z; x

$ ]% u2 G0 F: x6 M# b: C' O# S1 k7 e5.2 将工程实例化为静态协议栈工程编程基础
& U$ L$ B& w! V将工程实例化为静态协议栈涉及比较多的步骤,可以参考官方的文档 :BlueNRG-LP_LPS DK 1.2.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack\README.txt4 h4 v' G, k2 \; \3 b
* j8 q/ N! G$ i3 v! z
以及 SDK 安装目录的 index.html 中的静态协议栈的介绍如下图所示。' A8 \4 e/ x1 n: Q2 _+ m
7 k/ d2 n: {4 s1 @* \* P: }
微信图片_20231116191827.jpg 5 x1 f$ s+ a2 f4 `' M! f% _4 _
: h* Z2 g+ S6 x) s- E/ w* c- v
如果在实例化 OTA 程序时,可能需要修改链接脚本和 Preprocesor Symbols 中下面几个宏(具体不同应用,不同 OTA 类型,具体需要定义的宏和宏的数值也不同):   ?1 K4 i5 s7 `* ?% x
* f! a2 d" Z) k2 c" h- y
RESET_MANAGER_SIZESERVICE_MANAGER_OFFSETSERVICE_MANAGER_SIZEMEMORY_FLASH_APP_SIZEMEMORY_RAM_APP_OFFSET
5 b' j! ^- _/ j& x6 \7 W

# q6 e% b$ u+ X  D  B7 e5.3 使用默认配置的协议栈
" z0 Y9 A- H1 f  ^. _! y3 V如果使用了 OTA,发现空间不够,可以考虑将应用协议栈和 OTA 协议栈合并使用如下图所示。( f) f" p$ @! P# _
+ i% Q. U# n8 {9 w2 h% m/ m- Q1 C
微信图片_20231116191823.jpg , L. c" w5 @+ D/ u. n% y

0 E. |- n0 Z% `! f/ ]) l% C上图列举的是基于 BlueNRG-LP 的默认提供的工程的大致数值(BlueNRG-LPS 类似,这里不再举例)。如果遇到不同的应用,可以实际裁剪协议栈适配不同的应用需求。" L7 U! L# B8 l8 ?" A
; q& F2 p* V9 r) P. Z; `! k, q7 X
5.4 使用自定义配置的协议栈
+ U: t+ z2 S. _' E" O! W. B; g使用静态协议栈可以实现更为精确的函数级别的裁剪:通过注释协议栈工程中的 bluenrg_lp_cmd_if.c 中的 cmd_call_table 中对应的函数,编译时可以将不使用的协议栈函数裁减出协议栈。
- B% O# n9 l3 q7 C0 F2 N
& }8 m# m8 x  N
微信图片_20231116191820.jpg
9 ~$ G6 [9 U8 Z' X0 _9 z! s! t
4 u3 J) Y2 a# a6 c, {* z1 c
5.5 使用静态协议栈这种模式如何支持升级协议栈4 z$ e& s; ~6 F" C) \
当使用静态协议栈,默认协议栈就无法升级。为了能够支持协议栈也升级。需要增加一段 boot代码,当升级协议栈时,先放置在 APP 区域,当升级完协议栈后,将 APP 区域的协议栈拷贝到协议栈区域。接着继续升级被擦除的应用程序。Boot 代码决定搬运协议栈和跳转到下一级。8 q) W0 S: e3 Z0 h0 ?

5 V* Y5 J& f% M. R3 d% M
微信图片_20231116191817.jpg ( R) Y+ E8 Y2 \2 r5 h; ^

7 R7 G# D7 w  z; ]6 f0 M( r06优化后空间仍不足的其他方法! `1 }) n0 A; r7 p) C. B' q
如果使用静态协议栈和空间仍然不足,可以考虑将一些常用而不需修改的通用模块编译进协议栈的工程。如果空间仍然差距比较远则考虑用片外 Falsh 或者选用 STM32WB 系列,再或者使用 STM32+协处理器模式。
# w; [7 K+ _/ }) b" l
5 V' t$ A4 p( [6 s
% i' Z8 ]# v* T6 M7 T# S
转载自:记帖
$ P9 y+ f/ E: D/ [: y$ u$ _如有侵权请联系删除
# i) C5 Y, V6 {0 T6 x
. ?) ^8 v9 p8 D7 X3 F" W
9 M2 V/ H( W1 f' T$ ~
$ n: w( C0 X1 _" S) }
收藏 评论0 发布时间:2023-11-16 19:19

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版