将arm cm3汇编代码从flash重新定位到ram

时间:2012-11-21 23:07:42

标签: assembly arm cortex-m3

我的Cortex M3部件带有特殊类型的闪存。该部分在此FLASH上启动,但我需要运行一个函数来优化FLASH的速度。执行此操作的唯一方法是跳转到RAM并在那里执行这些功能(因为如果在正在优化的FLASH上运行,函数将崩溃)。

ARM允许分散加载。这是一个解决方案,因为我可以将函数放入RAM并在我到达main后运行它们。但是我不想在没有优化的FLASH的情况下执行所有的分散加载。所以我想在main之前运行该函数,这意味着从重置处理程序或SystemInit(从重置处理程序调用)。

我编写了一些位于ROM中的汇编函数。在启动时,我调用我写的Relocate函数,然后将其他函数复制到RAM,然后我跳转到它们。这很有效。

我的问题是:

  1. 这听起来很疯狂吗?有没有更简单的方法来实现这一点(无需等待分散加载)?
  2. 在.s文件中,我有我将重新定位的函数。要使用这些重定位函数,我加载PROC标签,然后减去(FLASH - RAM)的偏移量。这感觉不便携。是否有另一种方法来计算重定位函数的正确PROC地址? 例如:

    foo     PROC
            ...
            ...
            ENDP
    
  3. foo从0x24000000的ROM开始,我需要将其移动到0x8000的RAM。有没有办法声明foo存在于0x8000,即使它必须存储在ROM中?或者有没有办法声明foo_reloc生活在0x8000?这也适用于THUMB代码,因为foo可能从0x24000001开始,需要在0x8001调用。

    谢谢, Nachum

1 个答案:

答案 0 :(得分:5)

  1. 不,这不是疯了。
  2. 不要担心重定位链接器应该为您处理所有这些。
  3. 将Flash配置功能放入分散文件中的单独执行区域。那么你唯一需要做的就是修改分散加载代码,先设置flash配置函数的执行区域,然后调用它,然后继续其他区域的分散加载。

    使用这样的分散文件:

    LR 0x0
    {
        ROM 0x0
        {
          * (+RO)
          * (+RW,+ZI)
        }
    
        RAM 0x18000 0x8000
        {
            foo.o (*)
        }
    }
    

    然后你应该得到一个像以下内容开头的图像:

    $a
    !!!main
    __main
        0x00000000:    eb000000    ....    BL       __scatterload ; 0x8
        0x00000004:    eb000028    (...    BL       __rt_entry ; 0xac
    

    您可以使用“魔术”链接器符号(例如“Image $$ RAM $$ Base”)编写自己的分散加载器,以手动执行RO,RW和ZI的加载(只需在其上设置您自己的“条目”符号)链接器命令行绕过默认的分散加载器),然后调用__rt_entry。

    由于Keil工具实际上是ARM工具,因此您可以在此处查看更多信息。

    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0101a/armlink_chdcgbjd.htm