Dav*_*idG 6 c microcontroller linker gcc ld
我正在使用 gcc 编译 ARM Cortex-M4F 微控制器的一些代码。我的应用程序使用大量数据,我已将这些数据方便地写入 C 文件中:大型整数和浮点数组、指向各种数组、各种结构的循环链表,诸如此类。
当我编译它时,它总共有大约 500K 的数据,加上实际应用程序的几百 K 数据。gcc 将所有这些数据方便地放入 .data 部分;然后 ld 尝试构建 elf,将 .data 部分放入 RAM,将 .text(代码)部分放入 FLASH。我使用的 MCU 没有 500K RAM,因此无法构建 ELF,但它有 1M FLASH。我尝试更改我的链接器脚本,以便将 .data 和 .text 都放入“有效”的 FLASH 中,但还有一些其他代码希望其数据进入 RAM,因此最终执行失败;我无法做出如此彻底的改变。
我需要的是告诉 gcc 将这个 C 文件中的每个对象放入 .text 部分,以便它可以与其余的不可变内容一起进入 FLASH,或者至少是我可以指示我的链接器的其他部分编写如何处理的脚本,以便它不会干扰在 RAM 中安装没有问题的现有 blob。我不知道该怎么做。这是我所拥有的一个非常精简的例子
/* data.c */
static char* option_array_0_0[] =
{
"O=0.40",
"K=FOO",
"JAR=JAR",
};
static int width_array_0_0[] =
{
0,
1,
1,
};
Window window_array_0[] =
{
{
option_array,
width_array,
},
};
/* main.c */
extern Window window_array_0[];
int main()
{
/* Do stuff */
}
Run Code Online (Sandbox Code Playgroud)
data.c、window_array_0 和它链接到的所有内容(或大多数内容,也许字符串数组将成为 .text?) 中的内容都被放入 .data 中,我的链接器脚本将其放入 RAM 中。我希望将其全部放在不同的部分中,然后将其放入 FLASH 中。其中有数千个此类类型的数组,以及数百个结构体和数十个其他信息位。这可以改变吗?作为测试,我用随机数据的 char[500000] 替换了我的“window_array_0”,并且编译时没有任何抱怨,所以我假设它将全部放入 .text 中(如预期的那样),我只是不知道如何制作它对任意对象都这样做。感谢您的帮助。
正如其他评论者指出的那样,“静态常量”项通常最终出现在 .rodata 部分中,该部分可能位于潜在只读内存中的 .text 旁边。需要注意的是,在您的情况下,它可能是真的,也可能不是真的,因为这是特定于特定目标的,并且可能会被特定构建过程更改(即链接器选项、通过__attribute__((section("name")))
C 代码中指定的特定部分、链接器脚本、构建后调整的二进制文件)各种 binutils 等)。
如果您需要精确控制内存布局并且您知道自己在做什么,则可以使用LD 脚本来完成。除此之外,它还可以让您指定文件 data.o 中的 .rodata 应放置在链接到可执行文件的所有其他 .o 文件的 .text 之前/之后。
您可以使用arm-<your toolchain variant>-ld -verbose
转储默认链接器脚本并将其用作调整的起点。
大多数编译器/链接器,如果将变量声明为static const
,它会将其放置在文本部分而不是数据中。显然,这些必须预先初始化并且不能在运行时修改,但这是进入闪存的唯一有意义的方法。