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

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

[复制链接]
攻城狮Melo 发布时间:2023-11-16 19:19
01引言
, G& f; k" }. n- t客户在使用 BlueNRG-LP/LPS 芯片时,增加 OTA 服务后常常反馈说,编译代码区域超空间了,需要帮忙优化一下。后文主要通过下列步骤进行分析和优化 BlueNRG-LP/LPS 的代码空间:; |! t  E4 e  \, y7 X; i' f# w
a. 通过分析 BlueNRG-LP/LPS 的 OTA 方式,让客户可以选择合适的方式;
  L+ }8 x0 A, _" N5 O- \b. 通过整体分析 BlueNRG-LP/LPS 的链接文件(*.icf/*.sct/*.ld)了解默认工程的存储分布;5 z8 ?: e2 W, Q) O) Q3 N# y
c. 通过裁剪协议栈,选择合适的协议栈功能,优化 BlueNRG-LP/LPS 的代码空间;+ o' j  u  x: e6 d. {
d. 通过使用静态协议栈,进一步优化 BlueNRG-LP/LPS 的代码空间;
+ L1 U: ]1 _8 {, b; t% Y6 G& X+ Je. 其他方案; ' J' i5 c5 X, X9 `3 Q

2 m8 {- P" G- g: k# n
微信图片_20231116191908.jpg 3 ?( K7 P6 W0 T7 G. e: {* ^# V
+ }* _+ w) M  w% C/ G+ t' f
总的来说通过两个维度来节省空间:一个是协议栈的裁剪维度:主要是通过修改宏配置实现编译对应应用需要的协议栈。另一个是 OTA 和静态协议栈的维度:OTA 和静态协议栈的选择流程图如下图所示: Y7 |9 N# b. }# t( s& z

! P- k  ?0 O3 _, [
02BlueNRG-LP/BlueNRG-LPS的OTA
# P  c4 Y6 P6 \2 F+ m- p2.1 OTA 的框架
3 J+ T' Y0 Y: F9 A& r1 q手机或者电脑做 GATT Client,给带 OTA 服务的设备升级。) B/ `) ]! J3 _4 _4 n1 _% R# N) ?
1 W/ ~6 A# i1 Y- Z& k3 K) D
微信图片_20231116191905.jpg " {8 k7 D( H  H3 p( X6 H

$ M0 J9 M3 e1 A& m- F+ q' O3 F7 U3 w
2.2 官方提供的 OTA 方式
7 e1 j: Q/ w5 ^2 v- m7 [默认提供的 OTA 应用和协议栈编译在一个固件上。4 G; |' a! F4 {: n: e4 W
a. 不带备份的(右图中的右半部分)& A* S& J9 {# K
升级服务程序在 Boot 端(OTA Service manager)。- _; W6 w9 v7 S6 h
省空间(存放了 2 份协议栈,1 份应用): o+ H6 m1 X7 L: P- }6 O! v
管理简单(只需管理一份应用)4 r* z: w9 i7 V) s$ {9 q4 f( R
b. 带备份的(右图中的左半部分)
8 T! L4 k9 ^) B; A: @. f+ H9 F升级服务程序在应用端
/ F2 f, g  o; R+ g1 \; U9 T更消耗空间(存放了 2 份协议栈,2 份应用)
( A( G: Q' s: _4 U0 |" l' P' @管理稍微麻烦(需要管理两份应用,Lower 区域应用不能放置 Higher 区域运行)5 k' {7 V" R2 j( {: Y) A/ n
更安全 % b1 L1 M+ @+ }: o, |

2 v' v5 R, P9 |4 s, j( E% {
微信图片_20231116191901.jpg
/ u4 ]" t5 y' [  f
8 j; q* i& g, \0 I8 D/ {; T3 Da. 不带备份的方式由以下组件构成:
$ l, k+ }/ l* I2 k+ w% y0 s! C# Q( sBLE_OTA_ServiceManager+ application0 |0 Y' p3 B/ m- V+ ?* m
b. 带备份的由以下组件构成:
' @2 C* `9 \( D6 v2 m/ Q' N0 D: ABLE_OTA_ResetManager +Lower Application (with BLE OTA service) orBLE_OTA_ResetManager + Higher Application (with BLE OTA service)6 E" f: t0 W, U; |- T' _
$ I7 v8 @; ^0 v$ L4 `; ]
对应在 SDK 中工程和配置如下图所示:
# L- @* _. a7 n3 T$ Y% v+ ~a.BLE_OTA_ServiceManager 配合 BLE_SerialPort 中的 Sever_Use_OTA_serviceManager
7 t$ i: j1 r' e4 P" |1 tb.BLE_OTA_ResetManger 配合 BLE_SerialPort 中的 Service_LowerApp_OTA 或者Service_LowerApp_OTA 使用7 [; }0 l: _( a  r- S/ d

: Y! x5 q( V5 I$ n
微信图片_20231116191859.jpg
* B, @& C0 S+ P  n
6 f5 |# R$ w, v( c. U! H% P) P6 a: p
2.3 使用带备份类型 OTA 升级错误变砖头问题
  i- T' Y7 ~2 d+ v5 x# g编译器编译的 Higher Application 如果放置在 Lower Application 的位置,程序无法运行。APP 程序可以知晓当前运行的固件是 Lower 还是 Higher APP。可以在编译固件 Higher Application 和 Lower Application 中加入一些标记,用于给升级工具识别,当前需要下载的是Higher Application 还是 Lower Application 或者是否混用。建议每次发布时两个应用程序都编译生成,不要人为来管理固件,否则容易造成混乱,应该让升级 app 自动选择对应的来升级。% a4 `/ w. Z/ A! t$ R8 }

! N2 G; M+ H( Y& Z* n5 K

$ }! `% O6 L( y1 T 微信图片_20231116191855.jpg 5 v  F5 g, Q; Q& G0 c
! ~' n2 U0 s& {) f  c( ?6 g# F

; x" G1 ?0 k% R; |: A4 [03BlueNRG-LP/LPS的存储分析
9 Q2 e7 o5 l  D3 H& k' Q' p9 j3.1 linker 中宏定义作用范围
1 R/ y' ~8 ?' R" |Linker 中可定义一些宏、用于指定链接脚本文件所需的配置。这些宏定义不作用于.c文件或者.h文件,只作用于链接文件(.icf 或者.sct 或者 *.ld)。1 ^: L8 X) Z( q) Y

% D# r9 x+ }# `

/ U, {# K& k4 Y# D% r) w/ T, q3.2 链接脚本文件分析(代码区域)
( `- [( Y. m6 U: d4 s不同的 IDE 所使用的链接脚本文件的格式不同。比如,Keil 使用“*.sct”文件,IAR 使用“*.icf”文件,而 TrueStudio 使用 “*.ld”文件。 : G$ l, E* v" f# l/ {
! _, z* `8 O: `# m# J
下面分析BlueNRG-LP最新SDK中BLE_SerialPort项目IAR工程目录下的BlueNRG_LP.icf文件, 其他IDE一样,可以进行类比。由于Flash的擦除必须是整页操作的,写Flash之前必须将对应的页擦除,所以Flash的划分需要2KB对齐。就算只使用到0.9KB,也需要划分2KB区域。
; A, D& s9 o3 g9 K4 R2 x+ e
' G2 j& J6 U+ Y2 C: d- z8 n8 M默认SDK中提供了4种程序的链接配置:
: u6 a5 Y+ i! Z1.CONFIG_OTA_HIGHER
$ q7 J/ [4 P9 R# R: t1 c2.CONFIG_OTA_LOWER: o. \0 B1 {/ x* W' P6 t
3.CONFIG_OTA_USE_SERVICE_MANAGER
% E4 m3 }! `( P4.其他
% h7 S" q( n4 c  M9 Q+ I( @
3 R. Y. `5 i! _, n+ d
微信图片_20231116191852.jpg
- z8 A0 ^' ]' s
9 }" U- y) K% T1 a
对于这四种链接配置编译后,代码区域放置在如下地址。BLE_OTA_ServiceManager 工程使用的是非 OTA 程序,而 BLE_SerialPort 中的 Sever_Use_OTA_serviceManager 工程使用的是CONFIG_OTA_USE_SERVICE_MANAGER。* y6 |! g$ H/ R+ n0 B' T. t# `; q

1 X) Z$ Q& H6 t! Z9 p
微信图片_20231116191849.jpg , Z- ?5 `; j' u; R8 X$ `" i
; n/ _7 `/ p: m3 ]
上述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限制这个工程编译的程序空间大小不能超过这个范围。( C- S  ~( o; _

: J4 B# E$ R% \8 Y% P如果在linker中没有定义MEMORY_FLASH_APP_SIZE,则对应的4种配置分别是:
9 E. J- j( q: m- o1 T4 \0 m0 z  Q9 s# s; S
微信图片_20231116191846.jpg $ ]7 l1 K! I/ c) q8 f5 M

# ]" a% r3 J6 K* A( X9 ~MEMORY_FLASH_APP_OFFSET: 定义程序编译链接地址的偏移(非OTA程序)。如果在linker中没有定义MEMORY_FLASH_APP_OFFSET,则对应的4种配置分别是:' N6 o* c/ G; c: C/ z  L

' S* [5 c4 z! v# v6 Q6 r: W
微信图片_20231116191843.jpg & ~7 ?$ l8 X( G: \; w& S

( ?* U' p4 M( g0 I/ L前面提到默认SDK中提供了4种程序的链接配置,本质上只是计算MEMORY_FLASH_APP_OFFSET和MEMORY_FLASH_APP_SIZE的方式不同而已,如果应用需要,也可以改动这个链接脚本文件。
+ W* k. D" P, \; t" ?" w0 S/ h3 d# {' J
4 p# L$ L' F  h2 O8 e* H7 Z) I
04通过协议栈的初步裁剪与自定义优化空间
9 z6 [6 _) h, E, C- s; ]# PSDK 中默认提供了 4 种默认配置的协议栈加一种自定义的协议栈配置(BLE_STACK_CUSTOM_CONF),如下图所示。
; K- y- c* X/ [  X8 o, B; Q1 ^" Z: O4 j
微信图片_20231116191839.jpg
" J$ e  o5 U8 b7 T' {: w7 `# \. K
9 h' Y7 J: w4 V) b3 g5 |1 j
上述 5 种不同协议栈的配置,本质上就是通过使用宏控制不同的特性功能是否打开。只是前面 4种提供了默认便捷的设置,而最后一种可以进行细粒度更细的自定义的协议栈。
! K4 c: m/ g0 I" m' @. g, h# ^. m# q" ?+ y
可以在 Preprocesor Symbols 中定义相关的宏来配置使用哪种协议栈配置。
) a/ q. l: l  k! N5 |# I/ D
0 U% f( \. ]# L0 R# B
微信图片_20231116191836.jpg 7 j" R4 A! U9 C& l& B! h

& B& q; E" F: y如果选用细粒度更细的 BLE_STACK_CUSTOM_CONF 协议栈配置,则在 其中在头文件“custom_ble_stack_config.h”中开关不同功能特性,大致占用的代码如下图所示。% C/ E  U0 K. J0 Z. `+ W+ Z! O
% A* T  h" f* U1 w2 S. I8 a& t
微信图片_20231116191833.jpg
5 a8 `- }1 h! |/ C$ }5 S8 |- S7 B7 G6 |5 l5 n; _$ j& N: r

- L; w9 _' T+ J  F* i05协议栈的进一步裁剪:使用静态协议栈
. K' ^- ~( j. D7 g/ A+ Z5.1 静态协议栈工程的 4 种默认的配置
8 S9 [9 W4 o* u5 l2 p# qST 官方 SDK 中已经提供了静态协议栈的 Demo,分为协议栈工程和应用工程两部分,路径为:C:\Users\user name\ST\BlueNRG-LP DK 1.x.x\Projects\BLE_Examples\BLE_StaticStack 静态协议栈工程默认提供了 4 种配置:6 F3 r4 Z* ?9 z5 j- V9 w' m
• Release
6 x: ~; a" K9 t, s• Basic. N* m7 U/ I8 G" W# r4 t
• OTA_BTL_ResetManager2 @: I0 i0 B5 X& y" G! C: Y% Q
• OTA_BTL_ResetManager_Basic' h) k' x! D! w2 N# Q/ Q: x" _

+ m( X! y- R) m! _- L# VC:\Users\user name\ST\BlueNRG-LP DK 1.x.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack
% P" T; ?% {8 ~& T• Release
4 }0 T, T* _8 K+ G2 u0 K4 z• LowerApp_OTA
- u) Y$ [+ C+ L# P( M( k5 ~( O• HigherApp_OTA) J7 h! }) ~/ t

: k, B9 {" Q7 j0 I0 U
微信图片_20231116191830.jpg 8 ~3 l* B- m+ ^8 D- X

9 R+ |+ M& o% c7 z那它们有什么区别呢?它们可以分为两组。8 W% {& x" U; e  c; J
+ q9 ^+ H2 ?; i; i: Z
Release 和 Basic 是一组:它们运行时都是由协议栈程序直接跳转到一个固定的应用上;
6 R5 ]! b# k5 C0 f! Y. b& x
$ d+ b. U8 i8 R6 K
Release 和 Basic 的区别:Basic 的协议栈配置是 BLE_STACK_BASIC_CONF, 而 Release的协议栈配置是 BLE_STACK_FULL_CONF。, v8 o8 c5 _- W, b' b: s
( @: t7 ]. S2 ~$ v: t+ y/ g5 T
不同的协议栈配置,包含的功能和占用的 Flash 空间也不一致。
$ E+ j) u- _( r3 y0 V  n6 R1 P2 _/ G• 不同的协议栈配置包含的功能请查看 stack_user_cfg.h
9 {6 w, r1 j0 F0 h# W• 占用的 Flash 空间可以通过编译的 Map 文件查看• 宏 RESET_MANAGER_SIZE 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
4 G% L7 a) N( l% t$ ?• Linker 中宏 MEMORY_FLASH_APP_SIZE 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
5 m+ }6 j* V& U/ Q# Q0 D" F
+ j5 w6 R. H3 x* q( ^) ZOTA_BTL_ResetManager 和 OTA_BTL_ResetManager_Basic 是另外一组:它们都是由协议栈程序跳转到 Lower 应用程序或者 Higher 应用程序; ) k; a4 h9 T& g0 M4 }8 g
, M1 h% e! D3 R  B$ H( f
• OTA_BTL_ResetManager 和 OTA_BTL_ResetManager_Basic 的区别:OTA_BTL_ResetManager_Basic 的协议栈配置是 BLE_STACK_BASIC_CONF, 而OTA_BTL_ResetManager 的协议栈配置是 BLE_STACK_FULL_CONF! J  [& H+ v4 h

3 M! t- j4 M- R0 a/ f+ |• 不同的协议栈配置,包含的功能和占用的 Flash 空间也不一致。
# r. l, W, }3 z0 }0 K  Vo 不同的协议栈配置包含的功能请查看 stack_user_cfg.h
) P6 `1 W1 _. Q1 T: E6 ^7 i' Bo 占用的 Flash 空间可以通过编译的 Map 文件查看
4 G9 h/ i: w# o5 B7 I  Xo 宏 RESET_MANAGER_SIZE 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。# E7 U6 S! h6 @7 W
o Linker 中宏 MEMORY_FLASH_APP_SIZE 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。 & g" r1 I" Y& m1 F: k- Q& N9 b

( c& P% F& g- C* Y/ t其中,一个工程负责生成协议栈,另一个工程负责应用,那么这里 BLE_StaticStack 中的Release or Basic 与 OTA_BTL_ResetManager or OTA_BTL_ResetManager_Basic 怎么和Release,LowerApp_OTA 和 HigherApp_OTA 组合呢?
: N0 f: g5 V: b) n6 n% J• BLE_StaticStack 中的 Release or Basic + BLE_SensorDemo_StaticStack 中的Release //不带备份 OTA 的使用固定协议栈的方法( W3 Y2 z4 g$ N$ ^& K) v
• BLE_StaticStack 中的 OTA_BTL_ResetManager or OTA_BTL_ResetManager_Basic + BLE_SensorDemo_StaticStack 中的 LowerApp_OTA or HigherApp_OTA //带备份OTA 的使用固定协议栈的方法
% K7 ^; M3 E# e! a/ f
  N2 d1 m" @! o5 w# {8 @7 C5.2 将工程实例化为静态协议栈工程编程基础1 }0 @9 z( Q0 Y, b8 T! q& J
将工程实例化为静态协议栈涉及比较多的步骤,可以参考官方的文档 :BlueNRG-LP_LPS DK 1.2.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack\README.txt/ ^' V. ~; c0 b

3 C6 o$ x2 l, w" t4 g以及 SDK 安装目录的 index.html 中的静态协议栈的介绍如下图所示。
: |  b( {8 b9 D4 Q7 [5 T7 x3 x5 a: g/ m. z7 ^$ D
微信图片_20231116191827.jpg 1 X# a% q) c( Q7 p0 T4 N/ A$ U% u

5 E1 s% G; ?  D1 @$ Q* a- @如果在实例化 OTA 程序时,可能需要修改链接脚本和 Preprocesor Symbols 中下面几个宏(具体不同应用,不同 OTA 类型,具体需要定义的宏和宏的数值也不同):
# v" M) Z8 s6 n( f- E5 p- ~% z4 E2 ?, H1 \' }5 x$ s8 h
RESET_MANAGER_SIZESERVICE_MANAGER_OFFSETSERVICE_MANAGER_SIZEMEMORY_FLASH_APP_SIZEMEMORY_RAM_APP_OFFSET3 S$ ~8 T+ e+ J* w# I6 G* |( |
/ O: u9 @* l$ a" r; i( n$ v
5.3 使用默认配置的协议栈
: S5 V& N9 _- t1 O如果使用了 OTA,发现空间不够,可以考虑将应用协议栈和 OTA 协议栈合并使用如下图所示。0 ~5 K0 X- {$ F; T4 i

1 T# v, E0 F- z6 _: @2 y
微信图片_20231116191823.jpg ( j6 p& u% D6 D' S8 g2 O

& q. M0 G( E9 k( s1 z, \上图列举的是基于 BlueNRG-LP 的默认提供的工程的大致数值(BlueNRG-LPS 类似,这里不再举例)。如果遇到不同的应用,可以实际裁剪协议栈适配不同的应用需求。
5 F( G/ ?: b% F) N* t. F9 v. h) Q) B8 ]2 m# z
5.4 使用自定义配置的协议栈
& @( o* k& \3 q) L使用静态协议栈可以实现更为精确的函数级别的裁剪:通过注释协议栈工程中的 bluenrg_lp_cmd_if.c 中的 cmd_call_table 中对应的函数,编译时可以将不使用的协议栈函数裁减出协议栈。
9 s4 v( K  d/ {- d; C1 g
5 m% U, q9 W. s# a; _9 s/ z
微信图片_20231116191820.jpg / d. U( h) Y# H. `* v4 F. Y! F

% a( M. p; p% K/ Z, k5.5 使用静态协议栈这种模式如何支持升级协议栈
- z  j) F- d, \- P) i# S/ V9 J当使用静态协议栈,默认协议栈就无法升级。为了能够支持协议栈也升级。需要增加一段 boot代码,当升级协议栈时,先放置在 APP 区域,当升级完协议栈后,将 APP 区域的协议栈拷贝到协议栈区域。接着继续升级被擦除的应用程序。Boot 代码决定搬运协议栈和跳转到下一级。
- ?* m0 K) i6 h) w. g. [0 h. Y. a6 Q2 J4 D) N; M
微信图片_20231116191817.jpg ( ^8 K$ [  l* a1 f( v& i4 v* u, o

$ G% u2 C/ y& f6 H6 H8 i; [06优化后空间仍不足的其他方法7 U; k! a, n# l4 \, n1 l6 B
如果使用静态协议栈和空间仍然不足,可以考虑将一些常用而不需修改的通用模块编译进协议栈的工程。如果空间仍然差距比较远则考虑用片外 Falsh 或者选用 STM32WB 系列,再或者使用 STM32+协处理器模式。/ `. a* @! i2 s, c. H2 c+ H  Q

# `  G/ q/ {* D$ H+ [0 Q' R5 y
, r2 d/ D) Y1 \: h. ~! G
转载自:记帖0 ~+ i6 m5 O! T4 u% N2 N$ X
如有侵权请联系删除
7 Q0 L4 C( _% V7 n+ |( D  S2 f% F) U7 s
; w. P" c! J+ r! q1 g; y; ^" r( Y% m

& b8 h3 G' d# Y: S- w
8 o1 K* @* o& v' q- W& A
赞 收藏 评论0 发布时间:2023-11-16 19:19

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版