【问题标题】:Getting the gcc linker to place multiple functions at the same address让 gcc 链接器将多个函数放置在同一地址
【发布时间】: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 和/或同步字。

标签: gcc linker embedded


【解决方案1】:

您需要使用链接器OVERLAY 命令。这允许存储位置和执行位置不同。您需要在运行时实现覆盖管理器(用于在运行时将代码复制到执行地址的代码),但这解决了链接器问题。

找到一个工作示例,从https://forums.parallax.com/discussion/163970/overlay-code-with-gcc 的 EEPROM 加载代码

【讨论】:

    猜你喜欢
    • 2012-12-09
    • 2011-12-07
    • 1970-01-01
    • 2011-08-19
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 2015-01-25
    相关资源
    最近更新 更多