在keil MDK中定义非初始化(noini)变量

具体

可以参考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" ,避免发生上述问题。

posted @ 2022-11-30 22:14  svchao  阅读(944)  评论(0编辑  收藏  举报