具体
可以参考ARM官方资料:ARM: Uninialized Variables Get Initialized
这里是对上述资料的总结, 该方法已在项目中得到验证。
方法:
分散加载文件如下:
定义了一个 UNINIT 段,并指定它不允许被初始化。
- LR_IROM1 0x08000000 0x00080000 { ; load region size_region
- ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
- *.o (RESET, +First)
- *(InRoot$$Sections)
- .ANY (+RO)
- }
- RW_IRAM1 0x20000000 UNINIT 0x00000100 { ;no init section
- *(NoInit)
- }
- RW_IRAM2 0x20000100 0x0000FFF0 { ;all other rw data
- .ANY(+RW +ZI)
- }
- }
使用方法
// Arm Compiler 5
unsigned long NI_longVar attribute( ( section( "NoInit"), zero_init) ) ;
// Arm Compiler 6
unsigned long NI_longVar attribute( ( section( ".bss.NoInit")) ) ;
//also modify one line of the scatterfile from:
// *(NoInit)
//to:
// *(.bss.NoInit)
注意
这里在 Arm Compiler 5 中使用的是 zero_init, 在 Arm Compiler 6 中使用的是 ".bss.NoInit"。
添加它的原因是:
首先,只有具有 UNINIT 属性的执行区域中的 ZI 数据保持未初始化状态。如果属性是 RW,那么数据依然会被初始化。
而,出于优化原因,Arm 编译器 5 默认将 8 字节或更小的全局 ZI 变量放入 RW 数据部分。如果代码中的变量小于 8 个字节,它将从 ZI 更改为 RW,从而导致初始化发生。
所以,这里直接添加 zero_init 或者 ".bss.NoInit" ,避免发生上述问题。