4bgcamcxmad6402145736.png
6 G$ g; C$ X3 |- T- r
; q& `( v% z X2 Y; O5 y( b: ~, j2 Q有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为:STM32G431RBT6。Keil 中没有这个关键字,而且会有版本的区别,下面分别介绍:
9 n; i1 S8 c! Z8 l6 d2 X
uopydfarsxq6402145836.png
' G8 |7 w# i- W$ E4 ~: |为了防止未初始化的变量被初始化为0,要将未初始化的变量放在一个特殊段内,这个段满足是ZI数据段(.bss),它的执行域(region)具有UNINIT属性。
9 P4 l; O, `* O" K4 r3 ?1.Arm? Compiler 5的操作- a* _& F3 `3 N! c
修改工程的linkerfile文件,*.sct文件
5 u$ C3 x9 \% S7 `- i5 z& l( r
d3flwmfuqra6402145937.jpg
7 y2 z5 e- x" Z+ E6 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
# Y1 I2 s5 [3 j% w" O8 o2. Arm? Compiler 6 的操作
5 \! T; w) S8 y3 V- F0 N 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 U& r0 H w" S$ {. p/ M& U
对于版本 AC5 和 AC6 具体区别可以参考 Keil 帮助文件中的描述:
( t. e6 Z6 t B7 p$ Z4 e" s
4d1k14o4ewg6402146037.png
1 _8 j7 S c0 T- D1 l==========0 _! Y/ m% W' E
往期回顾:如何提高单片机的运算效率之FPU
3 A" p* Y/ G. C O [/ ~6 v& q5 n蓝桥杯物联网教程汇总_240529# I7 e; P4 @5 B* l G q1 ^3 i
==========
8 L3 }1 o* _$ w0 i9 l" O5 o# J j) O, q2 G3 }; r
uizm3no10s46402146137.png
6 l1 f& v) }+ i: q1 m' w+ R6 A. d1 E( q) V; d4 d& i: C# x6 r2 ]
mq2auo34vtg6402146237.png
; |* E f+ z) }$ [
n: m0 r6 n9 g$ B! h7 }; z
vmphy1mavia6402146337.png
|