我有一个带有特殊类型闪存的 Cortex M3 部件。该部件在此 FLASH 上启动,但我需要运行一个函数来优化 FLASH 的速度。唯一的方法是跳转到 RAM 并在那里执行这些功能(因为如果在它正在优化的 FLASH 上运行该功能将会崩溃)。
ARM 允许分散加载。这是一个解决方案,因为我可以将函数放在 RAM 中,并在进入 main 后运行它们。但是我不想在 FLASH 未优化的情况下执行所有的分散加载。所以我想在 main 之前运行该函数,这意味着从重置处理程序或从 SystemInit(从重置处理程序调用)。
我已经编写了一些位于 ROM 中的汇编函数。在启动时,我调用我编写的 Relocate 函数,然后将其他函数复制到 RAM,然后我跳转到它们。这是有效的。
我的问题是:
- 这听起来很疯狂吗?有没有更简单的方法来完成此操作(无需等待分散加载)?
在 .s 文件中,我有要重新定位的函数。为了使用这些重定位函数,我加载了 PROC 标签,然后减去 (FLASH - RAM) 的偏移量。这感觉不便携。是否有另一种方法来计算重定位函数的正确 PROC 地址? 例如:
foo PROC ... ... ENDP
foo 从 ROM 的 0x24000000 开始,我需要将它移动到 RAM 的 0x8000。有没有办法声明 foo 位于 0x8000,即使它必须存储在 ROM 中?或者有没有办法声明 foo_reloc 位于 0x8000?这也适用于 THUMB 代码,因为 foo 可能从 0x24000001 开始,需要在 0x8001 调用。
谢谢, 那鸿
最佳答案
- 不,这并不疯狂。
- 不要担心重定位,链接器会为您处理所有这些。
将您的 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/