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

基于STM32的Keil、IAR、CubeIDE 中变量不被初始化方法

[复制链接]
STMCU小助手 发布时间:2023-11-26 15:43
01前言' S* T/ {, L, J
有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为STM32G431RBT6。
  J+ G% ?1 u. K3 w2 [3 o+ f$ G7 Y2 L
02 IAR 实现变量不初始化方法
; J& t* L2 {( ]2 ~* z! EIAR 实现相对简单,直接使用“__no_init”这个关键字即可,也就是在变量前面进行修饰:4 J' W: v9 B9 w0 E2 c) r

# x, o1 U: i$ y; Y) H
: I4 R) V* N" w, |
微信图片_20231126153703.jpg

8 W6 p. E% y# l0 ?3 d! [, q- p- u' K/ f
为了验证是否执行成功,可以考虑周期性让系统复位,看变量的变化,比如下面的示例程序让系统周期复位,会发现每次 Test_NoInit 数据都是在上次数据基础上增加 10,而不是被初始化后的数据增加 10。
- N# g- F6 e$ \3 y0 o( q
. s2 Y5 H1 i2 G' {3 ~/ p* }, @
微信图片_20231126153700.jpg
* C  z* ]; r9 d( s" m( K4 q3 d: l
, ^: L7 c% s3 s& m5 }# K. x5 m

* D( K- p" L* B03 Keil 实现变量不被初始化方法
. }- J, G8 \$ fKeil 中没有像 IAR 里面的这个关键字,而且会有版本的区别,下面分别介绍:3 b; H' F& H4 J& x) _. `% A

+ ]" H& o, ^& {" X7 q
微信图片_20231126153657.jpg
8 [% h5 w+ j" j/ x
图1.Keil 不同编译版本
8 ?% G& R1 t- ~+ H: N8 o

0 j7 x5 m4 ]7 E  S4 S* @' i; F为了防止未初始化的变量被初始化为 0,要将未初始化的变量放在一个特殊段内,这个段满足是 ZI 数据段(.bss),它的执行域(region)具有 UNINIT 属性。+ V7 ?+ }4 F+ U; i$ U  o) O. N

& l0 e; f4 Z8 ]2 F3.1. Arm® Compiler 5 的操作: \4 r$ X$ k4 {3 K
修改工程的 linker file 文件,*.sct 文件
8 |# n0 f' L' B+ o0 U2 o* l1 v8 h9 t

& D* y1 P- E, G
微信图片_20231126153652.jpg
/ ~# q  ^( f- z* e2 c
图2.修改默认 linker file

: |( c/ ^/ O  ?0 U; I7 Y/ b5 Y" s% ]: l5 L* a- U, Q
这边将 RAM 划分两个区间,其中 RW_IRAM2 就是我们要的变量不初始化区域,属性为UNINIT,定义一个 region 名字 NO_INIT.
# u2 T2 ]8 q: u8 ]% |
# \5 ~. {8 w- U9 M8 l
$ m6 B* X( X9 c' |9 d
微信图片_20231126153649.jpg
  M9 F2 [# T4 K. r3 F  q

# ~1 h/ o/ t1 n变量定义到这个 section,这边 AC5 要用到 zero_init 这个修饰。( f4 t" R# C3 Z$ p6 N, M: [
* R0 W+ T1 t' X9 |0 D

! @* |. q! V6 [% O$ m1 _
微信图片_20231126153639.jpg
% i1 d0 s/ Q' S3 d! q5 A

  V* b% ?: z- i# \% Q
& o$ b+ U% v! l- d1 m
3.2. Arm® Compiler 6 的操作- e& [6 U3 f9 T9 Y5 _* U# _
在 AC6 上面需要加入.bss 这个 ZI 定义,如下的 sct 文件修改:
% u( q7 @  Y6 c- u3 I  {7 j. `7 x5 }0 c3 Q

* p' F& x# _4 R" }
微信图片_20231126153642.jpg
* z2 D- z8 a4 ~" i) ~6 M3 I% U( y

4 V1 @! Q- x$ j) N5 W1 N6 k* f
# }) x4 J- F4 T9 F8 }  B
变量定义到 section 部分,AC5 和 AC6 也是有区别的,不再支持 zero_init 这个修饰,如下定义:0 m1 \! ?* _( N: v6 p) M

& u% [' }5 T3 _% K

5 J4 ?6 S( L* A+ q
9 a: ~; m' q5 R* ]8 h

" y' ^/ w. {: H  |, H对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:: t+ B5 Y) f# z/ y5 B. l# y
$ m2 g: }+ F9 e/ a) S) I7 N1 j& q1 f
; ~# y  e9 E8 o) T: G* P+ M5 q' |
微信图片_20231126153635.jpg
0 _: e- f4 U8 n; w% Z
图3.Keil 帮助文件关于 zero initialized
" [) ]6 n; d& f4 f" X7 R. t* z
6 b3 ]  b2 u* w. o0 H( P! L
3 S$ k/ b" P( b; G( s% o

: [0 K7 Z1 z/ }# b( H

/ {; J- Q6 Y* P% j. z3 q, Y4 Z7 Z/ ^' w, [: t/ W
; `. |$ X: u& A. Z! P* p% V
04 CubeIDE 实现变量不初始化方法% F1 b/ C+ M& W% Q7 l
CubeIDE 的实现和 Keil 有类似的操作,需要修改 linker file 文件*.ld。首先对 RAM 进行划分,划分出不初始化的 RAM 区域:2 Z/ Y8 ~: V  L4 J4 ~0 O

8 c6 v4 {) ]& e4 p# d
6 _; z0 A5 c# L" X4 y! z$ m
微信图片_20231126153632.jpg

# x# n: b( K8 S! J; a
图4.划分 RAM 区域

$ K5 R& p/ L9 h$ v" Z9 o
9 l1 D: A8 Q. c# U5 d2 a
3 H8 {- ?2 N3 C; h: ^  J& \
增加区域描述,并且加入区域名字:

4 H  \( C; j* ]6 M6 t* y' R0 U3 _/ O- V' I2 K2 \

' h! A3 K4 K6 P% Z
微信图片_20231126153629.jpg

/ A. v' R/ I5 w" M; X  O9 r. K
图5.区域描述,名字定义

# N% A' |$ F" }
, C2 P7 c, B( D, Y$ `' m' B; R

$ f6 e/ ~  J# d( m5 c  g0 k( f: W4 a+ X+ A
定义变量到这个不初始化区域中:. e+ }3 W- W! u* J3 k; Z" B
  L& G0 o  Y' m( c# v# v5 x: d1 p

9 h" K  a5 j. r# L
微信图片_20231126153625.jpg
9 z2 h  I  e( a# @3 I3 s+ |

4 {) }! ?: s" f1 m另外,还提醒一点,有些 STM32 系列有专门针对特定 RAM 区复位后是否会被初始化的 Option 配置位。比方 STM32L4 系列,想让 SRAM2 变量不被初始化,得配置选项字节中的 SRAM2_RST位。如下图所示:' l7 N: g% M' d8 t% s/ [

7 x7 x7 p. Q8 u; I
7 l* F, g1 I. U' H
微信图片_20231126153617.jpg

; T* k1 v4 z3 A7 V; n; U- ~# j3 k6 q+ }: ^

: V5 q0 |( v8 B) z; ]转载自: STM32单片机- p# R$ |# H* \0 I: x0 l
如有侵权请联系删除
: I- _# E' ?6 A  ?9 b4 _) F; C$ ?- Y  G/ L' _% T
! w6 K4 e0 K3 H2 b" w7 z
微信图片_20231126153645.jpg
收藏 评论0 发布时间:2023-11-26 15:43

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版