引用网上的问题和答案
"单片机上电初始化后,RAM存储初始化全局变量,这些全局变量是从调试器烧进去的S19文件中获取的吗?" 这是个很好的问题, 全局变量和静态变量的初始化值是保存在Flash中的Const段里的 ,新建一个工程的时候默认有个startup的汇编程序文件,它负责将const段中的初始值付给这些全部变量。这些事情是发生在你的main函数之前的。
mcu启动后,程序运行需要的data段、bss段在mcu startup阶段拷贝到ram中。
在烧写的时候,这些值都放在了s19文件中,统一烧写到rom code flash中。
结合项目做了记录总结:
段定义
-rom=.data=.data.R
-start=RESET /00030000
-start=EIINTTBL /00030200
-start=.const, &
.INIT_BSEC.const, &
.INIT_DSEC.const, &
.text, &
.data /00038000
-start=.data.R, &
PubRam.bss, &
.bss, &
.stack.bss /FEDD0000
-start=BootRam.bss /FEDF0000
F1K的启动流程
cstart部分:
rom到ram的数据搬运
先贴代码
;-----------------------------------------------------------------------------
;section initialize table
;-----------------------------------------------------------------------------
.section".INIT_DSEC.const", const
.align4
.dw#__s.data,#__e.data,#__s.data.R
.section".INIT_BSEC.const", const
.align4
.dw#__s.bss,#__e.bss
;-----------------------------------------------------------------------------
;startup
;-----------------------------------------------------------------------------
.section".text", text
.public__cstart
.align2
__cstart:
mov#_stacktop, sp; set sp register
mov#__gp_data, gp; set gp register
mov#__ep_data, ep; set ep register
mov#__s.INIT_DSEC.const, r6
mov#__e.INIT_DSEC.const, r7
mov#__s.INIT_BSEC.const, r8
mov#__e.INIT_BSEC.const, r9
jarl32__INITSCT_RH, lp; initialize RAM area
在.INIT_DSEC.const段中放入了3个变量,#__s.data,(rom地址结束)#__e.data,(rom地址结束) #__s.data.R(ram地址开始)
这3个变量为编译器声明的,__s.data用来存放函数中全局变量的值,__s.data.R是代码中的值要搬运的ram地址,这些都通过map文件和段的声明来看
最后调用瑞萨库函数__INITSCT_RH;完成数据搬运工作;
官方文档:
_INITSCT_RH | CS+ V4.01.00 (renesas.com)
赋了初值的全局变量,这个全局变量的值放在了哪?
这个问题可以从map文件中看到答案
SECTION START END SIZE ALIGN ATTRIBUTE
RESET
00118000 001181f7 1f8 200 TEXT
EIINTTBL
00118200 001189ff 800 200 CONST
.const
00150000 001674e3 174e4 4 CONST
.INIT_DSEC.const
001674e4 001674ef c 4 CONST // const段
.INIT_BSEC.const
001674f0 001674f7 8 4 CONST // const段
.text
001674f8 0019ff41 38a4a 2 TEXT //代码段
.data
0019ff44 001a176f 182c 4 DATA //rom中存放存放有初值全局变量的初值
.data.R
fedd0000 fedd182b 182c 4 DATA(R) //启动的时候会把rom中初值搬运到对应的ram地址空间,至于搬到哪里,按照map中的映射地址进行搬运
PubRam.bss
fedd8ff0 fedd8fff 10 4 BSS
.bss
fedd9000 fede670b d70c 4 BSS
.nvm.bss
fede8000 fede85a8 5a9 4 BSS
.stack.bss
fede85ac fedea5ab 2000 4 BSS
BootRam.bss
fedf0000 fedf0fef ff0 4 BSS
其中关键的2行:
.data
0019ff44 001a176f 182c 4 DATA //rom中存放存放有初值全局变量的初值
.data.R
fedd0000 fedd182b 182c 4 DATA(R) //启动的时候会把rom中初值搬运到对应的ram地址空间,至于搬到哪里,按照map中的映射地址进行搬运
.data段为函数中有初值的全局变量在rom中存放的地方,这些值会随着烧写器下载到rom中,系统启动之后,会将这部分数据搬运到ram中,至于放在ram中哪里,这些都在编译阶段确定好了,可以从map中看到。
在cs+编译选项中,也有指定rom中data数据搬运到哪里:
这里明确了,从data到data.R中,搬运过程参考数据搬运一节
示例
_send_idle
fedd0010 1 data ,g 4
FILE=..\Output\Power.obj
fedd0014 fedd0027 14
比如全局变量send_idle,data段在0xfedd0000(ram段),在map中可以看到他的地址在fedd0010,系统在main函数执行之前,会把send_idle的值,从rom中搬运到fedd0010。
再往后就是系统正常运行了。