是否可以更改嵌入了 GNU Arm 的整个文件的默认部分?

Is it possible to change default sections for a whole file with GNU Arm embedded?

使用 GNU Arm 嵌入式工具链,是否可以更改整个文件的默认符号部分?

我以前使用过 Rowley Crossworks,它有一个参数,您可以为任何源文件或文件夹设置参数,以更改各种默认部分,例如零变量的默认部分: (来自Crossworks manual

这对于确保大型应用程序适合闪存和 RAM 资源受限的微控制器非常有用。但是,我无法找到使用常规 GNU Arm 工具链执行此操作的任何方法。

我知道我可以使用 __attribute__((section(".sectionname"))),但这需要修改代码,这在为不同的目标编译相同的代码时会出现问题,其中一些可能只有一个部分。

理想的解决方案是 GCC 命令行参数,例如将归零数据放入特定编译单元的自定义部分。然后我可以将其应用于 CMake 中的特定文件、文件夹或项目,而无需对实际源代码进行任何更改。有这样的东西吗?

使用 __attribute__ 是可能的,但是仅仅为变量键入一个部分是不够的。链接描述文件中必须存在这样的部分,这意味着您必须手动修改该部分(通常称为 .ld/.lcf 或类似的名称,具体取决于目标)。视目标而定,似乎存在各种方言,有关详细信息,请参阅 GCC 链接器手册。

Crossworks 为您完成了这部分工作——我记得他们让您修改更易于使用的 XML 格式,这样您就不必直接干预链接描述文件。您可以查看 Crossworks 的输出文件,您会发现一个扩展名为 .ld 或等效文件的文件。这可能就是给定目标平台的 gcc 链接器文件的样子。

您能否更改编译方法以生成 .s 文件,应用 awk / sed / 等...根据您的喜好调整部分,然后 assemble 结果。这是一种古老的方法,但非常便携且可靠。

我找不到此功能的命令行参数或类似参数,但 让我更详细地研究了链接描述文件,最后得到了这个:

.bss :
{
    . = ALIGN(4);
    __bss_start__ = .;
    *main.cpp.obj*(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
} >RAM

.ethram (NOLOAD):
{
    __ethram_start__ = .;
    *(.ethram)
    *(.bss*)
    __ethram_end__ = .;
} >ETHRAM

在上面我明确指出在输出部分 .bss 中只应包括 main.cpp 的 .bss 部分,并且它应该放在常规 RAM 中。然后在 ETHRAM 中有一个不受约束的 .bss,链接器将其他文件的 .bss 部分放在那里,这对我的使用来说已经足够了。

也可以像这样从输出部分明确排除文件,但我的应用程序不需要它:

.bss :
{
    . = ALIGN(4);
    __bss_start__ = .;
    EXCLUDE_FILE(*main.cpp.obj*)*(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
} >RAM