电子产业一站式赋能平台

PCB联盟网

搜索
查看: 26|回复: 0
收起左侧

嵌入式软件,如果想变量不被初始化,通常有哪些方法?

[复制链接]

502

主题

502

帖子

2191

积分

三级会员

Rank: 3Rank: 3

积分
2191
发表于 2025-1-2 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师( ]9 x% Q* F3 o) s! }5 V
关注我,一起变得更加优秀!
9 u, t  [1 x4 A/ A' K前言: H6 ~/ H8 N& k

# _' @" _2 T1 B) d: m7 I有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,2 g+ @/ `6 J+ l$ \
; A, g8 |5 f2 |
在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为STM32G431RBT6。
# ]2 ]1 |5 R% d( Q1 j2 E
8 b" H" r2 t3 x$ c% G: g9 Q9 BIAR 实现变量不初始化方法) b! y# o! ~* E$ U5 J4 v) z) ]
' p3 _! [* y! N# J8 w7 @
IAR 实现相对简单,直接使用“__no_init”这个关键字即可,也就是在变量前面进行修饰:/ E+ c) o  _" t( C$ X* m) n. S6 U
0 H' J& j: K: B+ i

y2hohuctb1464045626223.jpg

y2hohuctb1464045626223.jpg

+ C9 N& P, x2 h3 m' |# q( r
: H% P" g4 j2 S为了验证是否执行成功,可以考虑周期性让系统复位,看变量的变化,比如下面的示例程序让系统周期复位,会发现每次 Test_NoInit 数据都是在上次数据基础上增加 10,而不是被初始化后的数据增加 10。9 Q8 U9 ]7 V% ~: z- K$ b; \
$ L7 z0 B2 e% s  U' @. W

qnyanfnelbm64045626323.jpg

qnyanfnelbm64045626323.jpg

4 x* i1 U& o, f3 h+ T, W. U5 P' b4 \9 k6 b/ {3 P* o1 D
Keil 实现变量不被初始化方法% e9 d+ U$ @- w

8 B1 h& [7 N* cKeil 中没有像 IAR 里面的这个关键字,而且会有版本的区别,下面分别介绍:
0 w1 h* V! I+ B; q4 L" h$ T. [) `% m# g6 c7 F

ft3hxylfu5m64045626423.jpg

ft3hxylfu5m64045626423.jpg
7 w" h8 y8 G! c8 r7 P, ^
图1.Keil 不同编译版本9 e, I0 }% y+ g: Z/ P1 f) l
6 v: g) |# ]" H- b# b9 p
为了防止未初始化的变量被初始化为 0,要将未初始化的变量放在一个特殊段内,这个段满足是 ZI 数据段(.bss),它的执行域(region)具有 UNINIT 属性。
% o% z0 k3 E7 _& p+ f2 M  C" `0 {8 O* o
Arm? Compiler 5 的操作
: O! _) _0 ~% [& C" w: i+ m- G* m0 ~; V- z2 {4 q; x
修改工程的 linker file 文件,*.sct 文件
$ N, W" `7 A8 K1 T
4 W5 ^% l5 B' b7 k

ykue0cdyxqq64045626524.jpg

ykue0cdyxqq64045626524.jpg
7 L( `' g  H6 l. Z+ j- O
图2.修改默认 linker file2 u' k% H) X& t  U' n! F
  d2 L" ^6 [! y  f- Q4 Y3 T, |! Z. x' p
这边将 RAM 划分两个区间,其中 RW_IRAM2 就是我们要的变量不初始化区域,属性为UNINIT,定义一个 region 名字 NO_INIT.- {% j7 @3 O0 J) X
4 @/ i; `0 K) q/ }

h1123mqo5ev64045626624.jpg

h1123mqo5ev64045626624.jpg
% h( ]; |! c. Q' a

1 J  }3 Z% y; m' o7 Y3 V* m7 i变量定义到这个 section,这边 AC5 要用到 zero_init 这个修饰。
! y6 t* H6 r) V# F9 c, u  H7 X8 L. B/ L

tkttmdh0dx064045626724.jpg

tkttmdh0dx064045626724.jpg

2 O5 a6 A+ W! D" E
3 V- Z8 b8 n  \7 W0 C2 n% _3 fArm? Compiler 6 的操作- B# V$ i* j4 K; p! r4 R1 K/ ]& n

$ S! T9 A9 }5 `; I8 h" |在 AC6 上面需要加入.bss 这个 ZI 定义,如下的 sct 文件修改:" d# T3 B/ f2 M& y( a

- t! g- x* I( a4 F3 m( w

j1byteg0u2g64045626824.jpg

j1byteg0u2g64045626824.jpg

# `' U- F) [. d9 S: }  O: D
$ `9 O5 ~7 A5 I# S. @" O/ F% o变量定义到 section 部分,AC5 和 AC6 也是有区别的,不再支持 zero_init 这个修饰,如下定义:& R  @0 D' r0 u4 O$ k5 m4 q

# A; I& C5 _% l" O, \: G: Z* E/ r

lucwogwvlkx64045626924.jpg

lucwogwvlkx64045626924.jpg
- C0 G( J7 V* n1 _7 \
6 Y1 Y8 q' d$ S. p& l
对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:
, V0 I/ v0 M, c
2 B2 M4 n' S- G9 W: n

hdv5dmlcmd164045627024.jpg

hdv5dmlcmd164045627024.jpg

+ V: s5 h9 S6 Q$ E/ b5 L( a图3.Keil 帮助文件关于 zero initialized$ ?  G6 E4 ]8 U2 K! }
CubeIDE 实现变量不初始化方法
$ g% E& f+ [4 l9 D% D
. O7 E. J# N: @9 c, D: UCubeIDE 的实现和 Keil 有类似的操作,需要修改 linker file 文件*.ld。首先对 RAM 进行划分,划分出不初始化的 RAM 区域:" d; L/ E7 \; J3 a3 x2 w
+ S  x+ c4 j: C  _+ L

gcutovz5q5a64045627124.jpg

gcutovz5q5a64045627124.jpg
# V5 A3 R( s' ~6 W1 ?
图4.划分 RAM 区域, G, _5 z3 a1 K; s7 X  r6 g* G4 D
9 c$ p4 u" v( H: p9 L) n
增加区域描述,并且加入区域名字:
3 }" q7 @! h( Q/ p
5 _7 s7 H" m* @. A/ x

2hfr0cv3zmf64045627224.jpg

2hfr0cv3zmf64045627224.jpg
0 J' ^1 Q+ v% D4 e9 R
图5.区域描述,名字定义
+ W, T7 K# h( L+ ~, X8 C3 ]) l. w9 z% _/ R* [/ C
0 Z7 W1 ]9 V) O+ l
定义变量到这个不初始化区域中:7 y: d8 g& S& U1 Q

3 W' H) y- X: [+ a/ R: o, `

j25tid4fnte64045627324.jpg

j25tid4fnte64045627324.jpg
8 J5 C0 Z4 A/ a0 I
* y6 u/ ~9 [; W7 [3 A% e" ~
另外,还提醒一点,有些 STM32 系列有专门针对特定 RAM 区复位后是否会被初始化的 Option 配置位。比方 STM32L4 系列,想让 SRAM2 变量不被初始化,得配置选项字节中的 SRAM2_RST位。如下图所示:  s. H, i, g% U: X8 `: ~9 i

! a5 w0 O* l. A9 }; b

xrgi22yjjtv64045627424.jpg

xrgi22yjjtv64045627424.jpg

/ S% |' M' A) A; c' S; ]+ G! L6 ~来源:STMCU
+ z$ h+ _& R$ u" ]$ |# m文章来源于网络,版权归原作者所有,如有侵权,请联系删除。
, ~: l. j- c9 e( y# s+ d! N
' f% D2 D; W3 {! \7 o

vy5nkeewk3n64045627525.png

vy5nkeewk3n64045627525.png
5 C& K1 T/ f* k; t, q! e' g
) K* R% x" R$ `2 k4 t
- `4 H- i$ K3 j  Q: \# |
-END-
% B) @6 P# p' S, g7 R6 v! c- k往期推荐:点击图片即可跳转阅读" t8 a4 j3 H( A1 g$ z+ g4 M

. Y5 S3 V& P+ X0 p7 P                                                        , [# q3 q9 l5 \# \3 \; Y
                                                               
3 q: C3 I1 Z4 e. `& t                                                                       
( z: r1 x! s* [4 Z' ^0 V6 {) Z4 S                                                                                ( P/ S5 M0 f* n/ Q# Q/ `

rbfmgwqzz4i64045627625.jpg

rbfmgwqzz4i64045627625.jpg

, `% g: u( ~# B" H5 P! J8 N( l                                                                               
- _0 e: k% Z$ v0 {6 g, |                                                                                        嵌入式工程师的2024,这一年,感谢微信读书!, _* ~8 D/ ~, F$ A9 l
                                                                                7 z% j9 ]8 B( T8 ]+ k1 O
                                                                       
5 B1 U0 h. i4 t* e: f4 Y& t2 {                                                                ( k9 o; v/ A4 C  `( d, `
                                                       
0 V5 S% ]  |% I4 M6 [- B                                               
: X  s* k  @& h* Y" Y6 L3 s2 O, F
+ q* u& C0 b% x" D4 z8 W                                                       
2 y; e5 f- _( {* Y7 B/ ]                                                                # A, G# C9 ^7 g; k2 \
                                                                       
3 X5 d7 J+ w, m$ ?/ c                                                                                : k  I2 r5 ]3 O6 h3 q$ L

nrqzbwpv0lg64045627725.jpg

nrqzbwpv0lg64045627725.jpg

5 T* o1 c: N* Q; E  X                                                                               
$ G6 I  e) T3 R$ c: N  c                                                                                        嵌入式 C 语言编程,如何有效防止内存泄漏?
* m- L& U: g* w% |7 H9 [* |                                                                               
) i  w- W  ^/ _/ Z                                                                        3 Z/ \& `4 u5 R- T5 E; @
                                                                - l. O6 q% `8 @3 V- R1 N1 @, ?
                                                       
3 E8 Z. e. e$ d- z+ |/ y0 p                                                / {9 \# B7 o# O+ Z
# T) Q% \3 s$ Y9 C& K% A" y; g
                                                       
& w) F0 P& K( p, C, l) \) x2 E                                                                " X1 M* A' V, T  C/ e
                                                                       
& H: u2 R9 p" P3 B# z( T9 y- L                                                                               
+ O1 x# N! L5 E. }

2eupvh4vevu64045627825.jpg

2eupvh4vevu64045627825.jpg

4 e7 E9 f  H+ a. x1 s. R1 j                                                                               
+ c; J; D) r: o- X+ s: a' d7 D                                                                                        嵌入式 C 语言,位操作的几种常见用法。
2 ]3 y: L+ r/ I, B9 N4 @$ L% q                                                                                5 u! C! B8 L* m
                                                                        " `' I2 V# {: L" O  u
                                                                1 r5 O2 s$ X0 G# M
                                                       
8 y& d& E2 p( f) j                                                - E$ ~& r4 ~7 e
我是老温,一名热爱学习的嵌入式工程师9 N! l5 N2 A8 p$ F$ V1 M
关注我,一起变得更加优秀!
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表