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

引用网上的问题和答案

"单片机上电初始化后,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。

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值