3

我有一个带有特殊类型闪存的 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
    

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

谢谢, 纳楚姆

4

1 回答 1

5
  1. 不,这并不疯狂。
  2. 不要担心重定位链接器应该为您处理所有这些。

将您的闪存配置函数放入分散文件中的单独执行区域。然后你唯一需要做的就是修改你的分散加载代码,首先为你的闪存配置函数设置执行区域,然后调用它,然后继续分散加载其他区域。

使用这样的分散文件:

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”)编写自己的 scatterloader,以手动执行 RO、RW 和 ZI 的加载(只需在链接器命令行上设置您自己的“入口”符号绕过默认的分散加载程序),然后调用 __rt_entry。

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

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

于 2012-11-22T00:19:08.870 回答