3r5nnkwrwtk6402552435.png
# M- g: q5 ]" V5 k. l8 Q' g' k1 q! `4 w* ]& Y
有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为:STM32G431RBT6。Keil 中没有这个关键字,而且会有版本的区别,下面分别介绍:* \# ^1 E9 Q- w' y) G" A
mrfdgca5sqi6402552535.png
/ ?6 M! }6 ^, R) `" |为了防止未初始化的变量被初始化为0,要将未初始化的变量放在一个特殊段内,这个段满足是ZI数据段(.bss),它的执行域(region)具有UNINIT属性。! @0 N$ K/ z# z
1.Arm? Compiler 5的操作) [& m7 E" T% D9 O2 Q8 W& r6 H- n3 k
修改工程的linkerfile文件,*.sct文件
1 N) c! A5 Y" a; h3 {" [
ngx5ms0d2hg6402552635.jpg
+ [6 Q& b/ f$ E& ^1 _这边将RAM划分两个区间,其中RW_IRAM2就是我们要的变量不初始化区域,属性为UNINIT,定义一个region名字NO_INIT.ER_IROM1 0x08000000 0x00020000 { ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)} RW_IRAM1 0x20000400 0x00007C00 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x20000000 UNINIT 0x00000400 { .ANY (NO_INIT) }}变量定义到这个 section,这边 AC5 要用到 zero_init 这个修饰。uint16_t Test_NoInit __attribute__((section("NO_INIT"),zero_init)); // Work for AC5% i% s& R1 r( Q$ f. D6 @& |" M0 A+ k
2. Arm? Compiler 6 的操作
& P9 `1 h# d& @7 e0 v在 AC6 上面需要加入.bss 这个 ZI 定义,如下的 sct 文件修改:RW_IRAM2 0x20000000 UNINIT 0x00000400 { .ANY (.bss.NO_INIT)}变量定义到 section 部分,AC5 和 AC6 也是有区别的,不再支持 zero_init 这个修饰,如下定义:uint16_t Test_NoInit __attribute__((section(".bss.NO_INIT"))); // Work for AC68 B$ I/ Z/ U% g" o7 m) p
对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:
$ B- q' N: n9 L6 V' ]% s7 y1 M
orwn35asehz6402552735.png
3 L( |" l- h! @( [. F1 P==========
, ]. f" y2 o7 P, q# F) d往期回顾:如何提高单片机的运算效率之FPU$ Y3 I2 Q! b; o6 m" y2 b
蓝桥杯物联网教程汇总_240529 {9 `7 X. W3 |) q! [
==========/ E9 s4 n: h1 M; N" Q# f% U) A/ S
" g1 R1 i% b$ A' s0 O' k
zdcdowij13r6402552835.png
# X/ _5 n' \/ c0 W' }! g, ]
4 E9 ~' u: v3 ^9 }1 p" g
403bnlsdlij6402552936.png
. P! w* m& J9 B
# R5 h$ K3 u% s5 a
ls4sbhnnef56402553036.png
|