uy3yekznzby6408163318.png
/ n" h* v6 ?* t& S, R' O
9 p* X, s c. B9 }+ C$ L有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为:STM32G431RBT6。Keil 中没有这个关键字,而且会有版本的区别,下面分别介绍:. Z$ n$ T0 }2 {( P) A! r7 Y
sd2aotdll1p6408163418.png
( q% c( w4 U, e0 l
为了防止未初始化的变量被初始化为0,要将未初始化的变量放在一个特殊段内,这个段满足是ZI数据段(.bss),它的执行域(region)具有UNINIT属性。
. @) f G0 ^7 b! G" h* V: ~1.Arm? Compiler 5的操作
$ m7 q% K) l, `修改工程的linkerfile文件,*.sct文件
: p7 m4 F& P' X7 \$ f
5nqp4oygpw36408163518.jpg
3 L* y3 Q5 H+ G6 @* a
这边将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 AC53 Q& g# Q* _* y5 F- t
2. Arm? Compiler 6 的操作
" Q' T- P, J2 @3 R8 } F3 W在 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* R# U/ u' R' m5 b% e) r# p/ u
对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:
8 x& `( i7 g* g9 }# N6 Z
l2upsodwnan6408163619.png
; t; H( r# G0 w' |. Z* b==========
+ K+ W: E: n! i) W1 i2 n+ u往期回顾:如何提高单片机的运算效率之FPU3 l" k4 p, e3 j# `% s
蓝桥杯物联网教程汇总_240529/ n3 W: d' M7 s; A- W4 H
==========
8 n1 O1 C: R/ i% `( k9 e$ E& G) ^9 i) p! E
2xfhicphc506408163719.png
( L7 k7 G2 p! H( F! G9 c
2 ?( K6 V% u- L! V" C1 w# J
iowctq5z1js6408163819.png
* K$ u4 H' L* Y' H4 i5 U; D ]; `. r" z" e# B# {5 M
euxtdgaip1t6408163919.png
|