assembly - 将 arm cm3 汇编代码从闪存迁移到 ram

标签 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
    

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

谢谢, 那鸿

最佳答案

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

将您的 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

关于assembly - 将 arm cm3 汇编代码从闪存迁移到 ram,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13503529/

相关文章:

gcc - 与 Intel 语法相比,AT&T 语法中源操作数的顺序是什么?

c - 带有 objcopy 的巨大二进制文件

ARM Thumb/Thumb-2 性能

gcc - 使用 ARM Cortex-M4 和 gcc 编译器进行定点数学运算

arm - 为什么 Cortex-A 的复位处理程序位于 0x0 而不是 Cortex-M3

c - ATMEGA USART 处理方向键

c++ - 为什么会发出如此复杂的代码来将有符号整数除以 2 的幂?

c++ - 组装拆卸

assembly - 在 ARMv7a 和 Neon 上通过 64 位签名比较来支持 CMGT 的最有效方法是什么?

android - 如何在 ARM NEON 中将 uint8x8_t 加载到 float32x4?