项目中会用到复位原因等变量, 希望它们在复位后不被初始化, 保存复位前的一些信息, 方便处理.
在IAR中有关键字 __no_init, 它的作用是复位后不初始化这个变量.
但是stm32cubeide中不支持变个关键字.
stm32cubeide工程中, 变量初始化是在startup_stm32f072c8tx.s中执行的,
默认的启动过程如下:
1. 链接脚本中的ENTRY: 先执行 Reset_Handler函数, 这个函数是在
/* Entry Point */
ENTRY(Reset_Handler)
2. Reset_Handler (startup_stm32f072c8tx.s中) 的内容:
- 设置SP;
- 调用 SystemInit
- 初始化 .text section;
- 将.bss段内容清0
- 初始化libc: bl __libc_init_array
- 跳转到main: bl main
上述第3步中, 初始化 .text section; 的汇编代码如下, 将RAM地址 _sdata 到 _edata的RAM空间初始化:
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
其中的 _sdata _edata是在链接脚本定义的
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
所以, 如果需要变量不被初始化, 就不能将数据放在 _sdata 到 _edata的RAM空间里面;
可以在.data section之外再定义一个加载到RAM的section;
也可以在.data section中将数据放在 _sdata 到 _edata 之外, 如下所示;
*(.no_init)
_sdata = .
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
*(.no_init) /* .no_init sections; 放在_sdata之前; to avoid init during startup;*/
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH