我在工作中继承了一个 STM32 项目,该项目最初是使用版本 9 Quarter 2 GNU 编译器和 newlib nano 库构建的。该处理器只有 16K RAM,并且在使用库版本 10 及更高版本构建时会溢出。 溢出是由于链接中包含 findfp.o 模块引起的。
我对映射文件进行了一些调查,并在库的版本 9 和 10 之间进行了一些更改,以便 findfp.o 现在包含在链接器输出中。
进一步的调查显示 findfp.o 实际上在版本 10 中被引用,但版本 9 编译器似乎在链接阶段删除了未引用的 RAM,因为我发现版本 10 在库中没有更多的 RAM 使用,但在应用程序代码中使用更多。 看起来版本 9 编译器/链接器删除了已初始化但未使用的静态 RAM 位置。 我尝试了选项 -ffunction-sections 和 --data-sections 但这没有什么区别。如果我可以尝试另一个编译器选项,那将会很有帮助。
我还检查了STM32CubeIDE中选定的选项,发现“丢弃未使用的部分(”-Wl,--gc-sections)”,“将函数放在自己的部分中(-ffunction-sections)”和“将数据放在自己的部分中部分(-fdata-sections)”均已启用。
版本 12 在 findfp.c 中添加了 __sf,__sf 是 3 个 FILE 结构的数组,占用 323 字节的 RAM。
#ifdef _REENT_GLOBAL_STDIO_STREAMS __FILE __sf[3]; #endif
RAM 对于这个项目来说非常紧张,如果可能的话,我想知道如何让编译器像 9 那样优化未引用的 RAM。 不确定我能对 __sf 数组做些什么
我可以使用固定工具链 9-2020-q2-update 让项目正常运行,但最好能够使用最新版本,以便我可以利用任何修复/改进。
当我偶然发现从基于 GCC10 newlib 的裸机工具链开始令人惊讶地增加的图像和 RAM 大小时,我尝试了很多方法来找出并摆脱仅用于 stdio 文件描述符/指针的
__sf[3]
数组,即 stdin/out/err
我根本没用过。__sf[3]
的对象模块以及从 libc 引用它的另一个对象模块(在我的例子中是 libc_nano)。您可以手动从 libc 模拟中删除
findfp.o
和 fwalk.o
到此示例,目标为 libc_nano
(针对特定架构):
arm-none-eabi-ar.exe -d libc_nano.a libc_a-findfp.o libc_a-fwalk.o
或者使用强大的
find
GNU 实用程序为工具链包涵盖的发布和调试 libc(_nano) 版本的所有架构进行修补。arm-gnu-toolchain-13.2.Rel1-mingw-w64-i686-arm-none-eabi
):
find . -name lib[cg]_nano.a -exec bin\arm-none-eabi-ar.exe -d {} libc_a-findfp.o libc_a-fwalk.o ;
我个人的教训是:
最初尝试保留更多资源,以便为未来的扩展和/或更改做好更好的准备。如果可以的话,当然。