hxhxbnlzi2x64022959138.png
: H A' u, g4 L$ a; ] ]0 X- g4 {3 x
有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为:STM32G431RBT6。Keil 中没有这个关键字,而且会有版本的区别,下面分别介绍:' t( C% F: U- ~* }, G6 W; Y
30h1j40gap564022959238.png
. ~9 D1 ]/ o6 Y. n% O e
为了防止未初始化的变量被初始化为0,要将未初始化的变量放在一个特殊段内,这个段满足是ZI数据段(.bss),它的执行域(region)具有UNINIT属性。/ \$ g6 a6 @4 \. r
1.Arm? Compiler 5的操作 h' U; i' i8 ^- }5 f
修改工程的linkerfile文件,*.sct文件 e; ?5 q2 ~: A
gf4rdxtktoc64022959338.jpg
4 f- U* E" \. F这边将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 AC56 l7 z" i, s% K& ?% x3 G
2. Arm? Compiler 6 的操作9 W* L* H% F1 F% i! ^
在 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
/ _; U2 s- i, r% v5 f# {对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:0 o4 K( D! b N" S. s
tageiin4tmx64022959438.png
. g1 q) Q4 w/ Q; U. E6 p4 ^==========
' B. |! ^! S. t# G; x往期回顾:如何提高单片机的运算效率之FPU
/ S1 b/ w9 p' C- r I* ^4 g蓝桥杯物联网教程汇总_2405294 O$ Y: M8 p0 F+ C& h- I2 r
==========
0 L: }1 k& F7 j0 {; q2 e: |6 e) a0 C: F2 ^! S- v* Z
si4ggn2giu564022959538.png
6 ]# F8 g9 C, b7 A
! m' c8 K. }% C. [0 d0 l' O
x1neg4vjyb064022959638.png
1 R$ R& e& N8 u8 J; [; r" g
% t: r+ Z6 N: ^# W/ `5 b+ \
a4ctb10carp64022959738.png
|