问题描述
使用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 / etc ...来根据自己的喜好调整各个部分,然后组合结果。这是一种古老的实现方式,但具有相当的可移植性和可靠性。
,我无法找到此功能的命令行参数或类似参数,但是comment from Lundin使我更加详细地研究了链接描述文件,并最终得到了这一点:
.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