当前位置:   article > 正文

关于mcu启动中内存数据搬运的总结_initsct_rh

initsct_rh

引用网上的问题和答案

"单片机上电初始化后,RAM存储初始化全局变量,这些全局变量是从调试器烧进去的S19文件中获取的吗?" 这是个很好的问题, 全局变量和静态变量的初始化值是保存在Flash中的Const段里的 ,新建一个工程的时候默认有个startup的汇编程序文件,它负责将const段中的初始值付给这些全部变量。这些事情是发生在你的main函数之前的。


mcu启动后,程序运行需要的data段、bss段在mcu startup阶段拷贝到ram中。

在烧写的时候,这些值都放在了s19文件中,统一烧写到rom code flash中。

结合项目做了记录总结:

段定义

  1. -rom=.data=.data.R
  2. -start=RESET /00030000
  3. -start=EIINTTBL /00030200
  4. -start=.const, &
  5. .INIT_BSEC.const, &
  6. .INIT_DSEC.const, &
  7. .text, &
  8. .data /00038000
  9. -start=.data.R, &
  10. PubRam.bss, &
  11. .bss, &
  12. .stack.bss /FEDD0000
  13. -start=BootRam.bss /FEDF0000

F1K的启动流程

cstart部分:

rom到ram的数据搬运

先贴代码

  1. ;-----------------------------------------------------------------------------
  2. ;section initialize table
  3. ;-----------------------------------------------------------------------------
  4. .section".INIT_DSEC.const", const
  5. .align4
  6. .dw#__s.data,#__e.data,#__s.data.R
  7. .section".INIT_BSEC.const", const
  8. .align4
  9. .dw#__s.bss,#__e.bss
  10. ;-----------------------------------------------------------------------------
  11. ;startup
  12. ;-----------------------------------------------------------------------------
  13. .section".text", text
  14. .public__cstart
  15. .align2
  16. __cstart:
  17. mov#_stacktop, sp; set sp register
  18. mov#__gp_data, gp; set gp register
  19. mov#__ep_data, ep; set ep register
  20. mov#__s.INIT_DSEC.const, r6
  21. mov#__e.INIT_DSEC.const, r7
  22. mov#__s.INIT_BSEC.const, r8
  23. mov#__e.INIT_BSEC.const, r9
  24. 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文件中看到答案

  1. SECTION START END SIZE ALIGN ATTRIBUTE
  2. RESET
  3. 00118000 001181f7 1f8 200 TEXT
  4. EIINTTBL
  5. 00118200 001189ff 800 200 CONST
  6. .const
  7. 00150000 001674e3 174e4 4 CONST
  8. .INIT_DSEC.const
  9. 001674e4 001674ef c 4 CONST // const段
  10. .INIT_BSEC.const
  11. 001674f0 001674f7 8 4 CONST // const段
  12. .text
  13. 001674f8 0019ff41 38a4a 2 TEXT //代码段
  14. .data
  15. 0019ff44 001a176f 182c 4 DATA //rom中存放存放有初值全局变量的初值
  16. .data.R
  17. fedd0000 fedd182b 182c 4 DATA(R) //启动的时候会把rom中初值搬运到对应的ram地址空间,至于搬到哪里,按照map中的映射地址进行搬运
  18. PubRam.bss
  19. fedd8ff0 fedd8fff 10 4 BSS
  20. .bss
  21. fedd9000 fede670b d70c 4 BSS
  22. .nvm.bss
  23. fede8000 fede85a8 5a9 4 BSS
  24. .stack.bss
  25. fede85ac fedea5ab 2000 4 BSS
  26. BootRam.bss
  27. fedf0000 fedf0fef ff0 4 BSS

其中关键的2行:

  1. .data
  2. 0019ff44 001a176f 182c 4 DATA //rom中存放存放有初值全局变量的初值
  3. .data.R
  4. fedd0000 fedd182b 182c 4 DATA(R) //启动的时候会把rom中初值搬运到对应的ram地址空间,至于搬到哪里,按照map中的映射地址进行搬运

.data段为函数中有初值的全局变量在rom中存放的地方,这些值会随着烧写器下载到rom中,系统启动之后,会将这部分数据搬运到ram中,至于放在ram中哪里,这些都在编译阶段确定好了,可以从map中看到。

在cs+编译选项中,也有指定rom中data数据搬运到哪里:

这里明确了,从data到data.R中,搬运过程参考数据搬运一节

示例

  1. _send_idle
  2. fedd0010 1 data ,g 4
  3. FILE=..\Output\Power.obj
  4. fedd0014 fedd0027 14

比如全局变量send_idle,data段在0xfedd0000(ram段),在map中可以看到他的地址在fedd0010,系统在main函数执行之前,会把send_idle的值,从rom中搬运到fedd0010。

再往后就是系统正常运行了。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/272077
推荐阅读
相关标签
  

闽ICP备14008679号