4x5gjo2qwxk64014704440.png
0 P& u& p3 W7 h+ V% h( y" r; C+ @8 L2 d7 X0 `. y
有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为:STM32G431RBT6。Keil 中没有这个关键字,而且会有版本的区别,下面分别介绍:
( o0 r) \5 Z2 s+ t2 D* {6 V0 _
yrg3fiwmhkl64014704540.png
) @3 n; I: F4 f: I; B为了防止未初始化的变量被初始化为0,要将未初始化的变量放在一个特殊段内,这个段满足是ZI数据段(.bss),它的执行域(region)具有UNINIT属性。$ u9 E2 i3 L& ^4 c0 {) a- p
1.Arm? Compiler 5的操作* e6 Z$ p. Y: D& k: \
修改工程的linkerfile文件,*.sct文件
8 w" B- E3 @$ l# w7 m6 ~
4xjiuvnnufv64014704640.jpg
$ t/ d4 i2 m7 {' U这边将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( N8 G* S/ \6 v. k2 f- \
2. Arm? Compiler 6 的操作; {1 N, \' W4 J5 z8 W6 R
在 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 AC6' u' _, a6 ^- S
对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:0 j8 Y) J4 n/ ^4 p& r
woa30pql2nv64014704740.png
/ F3 w8 J V% O$ ^' z Q1 @
==========
$ y' h# X. O. {0 q, }, E1 Q/ P往期回顾:如何提高单片机的运算效率之FPU
# r4 c% r3 U7 A g7 w蓝桥杯物联网教程汇总_240529
( t) \1 P) l: b. t==========
2 q( D3 j9 i8 m, r" [* h
% V: `% i: R6 g( C$ R9 l
iykfrt4mxzv64014704840.png
2 E+ ]% Y b* Q2 ]" b% U) x, I) S; T+ G4 L; q* \" e
eznehhtth2y64014704940.png
- i, q) M6 w1 ^
: t: [6 o: p* n; r7 b3 _% v
qb03kd54hb164014705040.png
|