赞
踩
引用网上的问题和答案
"单片机上电初始化后,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
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
cstart部分:
先贴代码
- ;-----------------------------------------------------------------------------
- ;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
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
在.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
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
其中关键的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。
再往后就是系统正常运行了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。