打印
[其他ST产品]

lut1lut的"STR71x的UART进行IAP"为何需要手动再次拷贝

[复制链接]
2750|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lvpeng1979|  楼主 | 2007-11-20 19:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在lut1lut的“如何利用STR71x的UART进行IAP 补充说明 版本1.0”的方法中,用户程序要使用中断必须手动拷贝用户程序的异常向量表、启动代码和中断处理函数。(使用的是

api_segment_init.c)。而在用户程序的lnkarm.xcl文件里可以看到:
// put in ram area 
-Z(CODE)INTVEC=RAMSTART-RAMEND  //....ram : put 71x_vect.s in ram
-Z(CODE)ICODE=RAMSTART-RAMEND    //...ram : put 71x_init.s in ram
-Z(CODE)CODE_RAM=RAMSTART-RAMEND //.ram : put 71x_it.c really in ram

// declare in rom place
-Z(CODE)CODE_ROM_INTVEC=ROMSTART-ROMEND //  declare the rom place for 71x_vect.s
-Z(CODE)CODE_ROM_ICODE=ROMSTART-ROMEND  // declare the rom place for 71x_init.s
-Z(CODE)CODE_ROM=ROMSTART-ROMEND // declare the rom place for 71x_it.c

// transfer from rom to ram
-QICODE=CODE_ROM_ICODE               // transfer 71x_init.s
-QINTVEC=CODE_ROM_INTVEC          // transfer 71x_vect.s
-QCODE_RAM=CODE_ROM                   // transfer 71x_it.c

已经隐含调用了动态库完成了拷贝操作。

为何需要手动再次拷贝。难道此刻不能调用动态库吗。不能调用为何要做
// transfer from rom to ram
-QICODE=CODE_ROM_ICODE               // transfer 71x_init.s
-QINTVEC=CODE_ROM_INTVEC          // transfer 71x_vect.s
-QCODE_RAM=CODE_ROM                   // transfer 71x_it.c
这样的操作。做这样的操作只是为了看三个段的起始地址和大小吗?以便写api_segment_init.c中init_ram_code()的地址参数吗?
__root void init_ram_code()
{
... ... ... ... 
  memcpy((char *)0x20000000,(char *)0x40003000,0x428);
  memcpy((char *)0x20000428,(char *)0x40003428,0x1b8);   
  memcpy((char *)0x200005E0,(char *)0x400038DC,0x144);  
... ... ... ... 
}

请教各位DX,可能我有些概念没有弄清楚。
沙发
浪淘沙| | 2007-11-20 20:41 | 只看该作者

楼主想过没有,系统上电时RAM里是什么内容?

难道你指望断电后RAM的内容还能保持到下次开机?

具体为什么这么定义,lut1lut看到你的问题后会回答的,我只是提醒一下楼主的思考方向。

使用特权

评论回复
板凳
lut1lut| | 2007-11-21 11:10 | 只看该作者

因为没有动态库来给你自动完成阿(1)

在第一个版本(version 1.0)中介绍了将app的中断向量表拷贝到ram中,使得可以在ram中响应app中断的办法。

从bootloader的运行到app的正确运行,又两个阶段:Phase A : bootloader运行;Phase B : app运行。

PhaseA中,因为要对flash操作,所以需要将部分代码拷贝到ram中运行。于是通过在bootloader的IDE和bootloader的linker file中对CODE_Flash和CODE_ROM的指定,在bootloader的init.s中通过“B ?main”,在执行bootloader自己的main之前,先隐性调用了动态库,实现CODE_ROM到CODE_Flash的搬移。此时ram中是关于flash操作的一些代码

 

使用特权

评论回复
地板
lut1lut| | 2007-11-21 11:11 | 只看该作者

(2)

bootloader运行完成后,跳到0x4000,2000,即"api_segment_init.c"来执行,进入PhaseB。这个api_segment_init.c就是将app中需要放在ram中的代码进行搬移。(这个时候ram里放的是app的INTVEC/ICODE/CODE_RAM的代码,不再是之前PhaseA时bootloader中关于flash操作的代码) 然后直接通过asm("b 0x40003000")跳到app自己的main.

就是说PhaseA可以自动完成拷贝是因为通过“B ?main”跳过去的;而PhaseB中手动拷贝是因为通过asm("b 0x40003000")直接跳到app的main执行的。
并不是在linker file中指定了"-Qsegment1=segment2",就代表系统会一定调用动态库来自动完成拷贝!像PhaseB这样直接跳到0x40003000开始执行,哪里有动态库执行的机会呢! 

使用特权

评论回复
5
lvpeng1979|  楼主 | 2007-11-21 14:14 | 只看该作者

可以这样理解吧

可以这样理解吧.

整个软件可以看作是基于bootloader的一个项目,app可以看作这个项目里的一个部分程序,而linker file中指定的"-Qsegment1=segment2"动态库自动拷贝只是针对bootloader。不存在针对app的第二个linker file。只存在一个linker file,所以app的INTVEC/ICODE/CODE_RAM的代码需要手动拷贝。

这个手动拷贝动作是代替了单独编译app项目时的linker file中的"-Qsegment1=segment2"。

使用特权

评论回复
6
lut1lut| | 2007-11-22 11:54 | 只看该作者

不能这样理解

bootloader和app有各自的linker file,并且都用了"-Qsegment1=segment2"。但是有这个连接说明,并不代表会有动态库来给你自动拷贝。

bootloader中从自己的init.s跳到自己的main,用的是“B ?main”。你可以去单步跟踪一下,先调用了动态库,用memset/memcpy根据linker file中的连接说明进行拷贝搬移。

app是从api_segment_init直接通过“b 0x40003000”跳到自己的main,没有调用动态库(用memset/memcpy去拷贝搬移);所以我自己手动去做了。我怎么知道从flash的哪里拷贝到ram的哪里呢? 所以要先看看app的map file中连接过后的地址值咯!


bootloader: 
init.s --> 动态库用memset memcpy根据bootloader.map中的地址值拷贝 --> main.c

app:
segment_init.c手动用memset memcpy根据app.map中的地址值拷贝 --> main.c

使用特权

评论回复
7
lvpeng1979|  楼主 | 2007-11-22 19:15 | 只看该作者

非常感谢你的详细解释。

非常感谢你的详细解释。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

36

帖子

0

粉丝