c - GCC:为实际符号指定目标地址

标签 c gcc linker symbols

知道类似的问题已经被问过几次了,让我解释一下我想做什么以及为什么:我有一个嵌入式系统,它由一个 ARM Cortex-M4 微 Controller 和一个 FPGA 组成。 FPGA 可以通过板载闪存进行配置,甚至不需要微 Controller 。但有时微 Controller 能够重新配置 FPGA 会很好,这样它就可以访问所需的编程信号。

需要发送到 FPGA 的比特流约为 150kBytes,但变化频率远低于 MCU 固件。由于使用编程器/调试器 (Segger J-Link) 对那么多数据进行编程需要一些时间,所以我不希望每次固件更改时都删除和重新编程该比特流(但比特流是相同的)。调试器只对那些实际发生变化的内存块进行重新编程,因此如果比特流始终位于同一地址,它就会愉快地跳过对比特流的编程。但如果我只是以某种方式包含它,这显然不是这种情况

static const uint8_t fpga_bitstream[] = {
  // ...
};

因为链接器可以自由决定将这些数据放在哪里。

现在的问题是:让链接器始终将此符号放在同一地址的(不太侵入性的)方法是什么?我知道 --defsym 链接器选项,但是当相关符号在源文件中定义时(而不是仅仅被引用并声明为 extern)。我知道哪个有效的唯一方法(我之前已经用过)是使用自定义链接器文件,该文件在 MEMORY 部分定义一个单独的分区,然后创建一个新部分来放置符号,使用例如

static const uint8_t fpga_bitstream[] __attribute__((section(".fpgabitstream"))) = {
  // ...
};

这个项目使用了一个小型操作系统 ( Nut/OS ),但是它有自己的链接器文件。所以如果我可以使用 -Tfile.ld 选项向它附加一些数据,我会很好,但我宁愿不必更改原始脚本,因为它位于源代码树中操作系统本身。

谢谢, 菲利普

最佳答案

因为似乎不可能“添加”到现有的链接描述文件,可能最简单的解决方案是保留一个单独的闪存区域(例如,一个位于固定地址近端的区域,并为 future 增长)用于 FPGA 配置并从该固定地址加载。

由于您可能无法从 MCU 端对 FPGA 比特流执行任何有用的操作(除了加载它),所以我认为将 FPGA 配置嵌入到您的 MCU 二进制文件中没有任何优势。您只需要 MCU 代码中的起始地址和大小,这两者都可以通过 --defsym 链接器选项(无需修改链接器脚本)让 MCU 知道。

我在这里有一个非常相似的配置(FPGA 配置和 MCU 代码位于闪存的不同区域),效果很好。 MCU flash 经常使用,而 FPGA 只是偶尔刷一下。

关于c - GCC:为实际符号指定目标地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29683399/

相关文章:

linux - 在嵌入式 Linux 平台上将 libc 与 JNI 代码链接 (GuruPlug)

c - 当我在 splay 树中遍历时,现在哪个是根?

c - 人们觉得 C 指针有什么困难?

c - Eclipse C/C++ (CDT) 添加 -l 选项(链接数学模块)gcc -lm

c++ - 在 mingw64 上使用 boost.thread 未定义对 InterlockedCompareExchange 的引用(但在 mingw32 上不存在)

我可以用我自己的版本替换静态库中的符号吗?

使用命令行参数计算矩阵行列式的 C 程序

c++ - 文件内加密文件系统

c - 为什么使用 -Os 编译会使这个函数变大?

c++ - 无法编译 : unrecognized relocation