【发布时间】:2020-02-12 11:27:14
【问题描述】:
我有一个带有内部和外部闪存的嵌入式系统。控制器为 MSP430F22x2,外部闪存使用 SPI 连接。我可以从外部闪存加载数据,但外部闪存不是内存映射的。由于内部闪存不够大,我想在外部闪存中添加功能。因此必须将外部闪存复制到内部闪存中,以便执行功能。这本质上就像是穷人的分页。
为了完成这一切,我有一个函数,它加载 flash 的右侧部分,然后调用该函数。它管理一个内部页面堆栈,与“真实”堆栈分开。如果我想在另一个页面上调用一个函数,我必须跳转到这个函数。然后该函数在现在加载的页面上调用该函数。当函数返回时,在管理函数中继续执行(因为它是从那里调用的),然后加载正确的页面并跳转回来。
问题是,这些函数都在内存中的相同位置,因为它们是被复制的。但是ram中的数据不能重叠。我目前的解决方案是为外部代码的每个部分使用单独的链接器脚本,并手动设置 ram 部分的地址。这当然很耗时,如果零件需要更多内存等,则必须更改所有内容。
单独的链接器脚本如下所示:
ENTRY(part)
SECTIONS
{
.data 0x2A4 :
{
. = ALIGN(2);
*(.data .rodata*)
}
.text 0x4000 :
{
*(.text)
}
}
没什么特别的。一切都设置为特定地址,不检查溢出。为了能够调用函数,我导出符号表并将它们添加到主链接描述文件中。这一切都是使用批处理脚本自动完成的。
所以我需要一个链接器脚本,它基本上将多个 .text 部分重叠放置在同一地址范围内,并且 .data 部分连续。
我不知道是否有办法做到这一点。真的任何解决方案(链接器脚本、批处理脚本等)都会帮助我。我唯一不能改变的是硬件。
【问题讨论】:
-
指定您使用的“嵌入式系统”?那是什么“系统”?这是否偶然有今天流行的 MCU 产品线,如 PIC 或 STM32?请发布您正在使用的
separate linker scripts?你是如何手动设置这些部分的?你用的是什么“外置闪光灯”?如果其他人不知道您使用的是什么硬件和环境,他们应该如何发布解决方案?My code does keep track of all this“跟踪这个”究竟是如何工作的?请编辑您的问题并添加其他信息。 -
最重要的是,外部闪存是映射到旧的外部地址总线,还是放置在串行 (SPI) 存储器中?
-
在实现这个之前,我会在裸机上实现动态库加载 (researchgate.net/publication/…)
-
@ralfhtp 这看起来很有趣,但他们拒绝了我的全文版本请求。你能把出版物提供给我吗?
-
从外部闪存加载代码并将其刻录到内部闪存听起来并不明智,您可能会耗尽擦除/写入周期的次数。您可以考虑改为从 RAM 运行该代码,但您可能还应该添加额外的安全措施,例如 CRC 和/或同步字。