n4k2nfevfuq64016755033.png
, P. @9 j2 k' I3 {& q6 ?3 x- l6 U. F3 ?# P( `/ D
有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为:STM32G431RBT6。Keil 中没有这个关键字,而且会有版本的区别,下面分别介绍:
" {6 m9 l$ C* G* d% ?
gdmck3s1xl064016755133.png
' P& m1 I& R" g5 N5 F* a
为了防止未初始化的变量被初始化为0,要将未初始化的变量放在一个特殊段内,这个段满足是ZI数据段(.bss),它的执行域(region)具有UNINIT属性。
4 A# j- c. m0 Y4 ?7 |5 C1.Arm? Compiler 5的操作
/ h' V; P) w; z# t, Y' X修改工程的linkerfile文件,*.sct文件# M" `- A( e3 p7 G& L: ~
5p1r05c3pey64016755233.jpg
" h3 l7 E8 e% l1 k
这边将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
" l' N1 T) R, ^2 N1 m2. Arm? Compiler 6 的操作
1 S, e9 W' z; k; L5 a在 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
: Q3 i1 D' r3 ~: g/ e$ V( t* z$ ?% U对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:
j; b5 {+ W o3 x' y7 t+ C0 ?
1yaqe3gmuqf64016755333.png
- R" T D' ]+ V- q" v4 ^% N
==========
0 T* s; h) w ^# L, X* k往期回顾:如何提高单片机的运算效率之FPU
2 x: W" E3 j9 }8 C# W0 m蓝桥杯物联网教程汇总_240529
' B. B8 d3 d" E% W. K==========2 P5 E& L) L( ]: Q
0 y& a. ^ R2 Q7 o+ [
mnocsppckmo64016755433.png
6 M, w/ g0 p" v4 M( V! {. f% ^
( ? I+ {- N( Y+ p f; Q5 k
3vc2orglarh64016755533.png
* T! _$ S9 t5 I. }# b% J7 [% Y
9 E6 u4 a6 x7 e m5 Z( J5 \, y
ayfxmht5gre64016755633.png
|