GCC [for ARM] 强制无浮点数

GCC [for ARM] force no floating point

我想创建一个我的嵌入式 C 代码的构建,专门检查浮点运算是否被意外引入其中。我已经尝试将 +nofp 添加到我的 [cortex-m3] 处理器架构中,但 ARM 的 GCC 不喜欢那样(可能是因为 cortex-m3 没有浮点单元)。我试过指定 -mfpu=none 但这不是允许的选项。我试过将 -lm 离开链接器命令行,但链接器似乎太聪明了,不会被它愚弄,并且正在编译带有 double 的代码并解析 pow() 无论如何。

这个 post: https://gcc.gnu.org/legacy-ml/gcc-help/2011-07/msg00093.html 从 2011 年开始暗示 GCC 没有这样的选择,因为没有人对此感兴趣,这让我感到惊讶,因为这似乎是一件很常见的事情,在至少从嵌入式的角度来看,以避免意外的 C 库膨胀。

有谁知道使用 GCC/newlib 执行此操作的方法,而无需我手动从它选择的 C 库文件中破解内容?

这不仅仅是图书馆的问题。您的目标将使用 soft-fp,编译器将提供浮点代码来实现算术运算符,而不考虑库。

我通常采用的解决方案是扫描映射文件以查找编译器提供的浮点例程的实例。如果您的代码是“fp clean”,则不会有此类引用。数学库和任何其他执行浮点算术运算的代码都将使用这些运算符实现,因此您只需要查找这些运算符调用,而可以忽略 Newlib 数学库函数。

https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html 列出了内部 soft-fp 例程。手动检查映射文件中的 fp 符号可能是可行的,但您可以自己编写一个脚本或工具来扫描映射文件中的这些名称以检查您的 .映射文件的交叉引用部分将列出使用这些符号的所有模块,因此您可以使用它来识别使用浮点代码的位置。

Newlib stdio 函数默认支持浮点数。如果你的格式化 I/O 被限制为 printf() 你可以使用 iprintf() 或者你可以用 FLOATING_POINT undefined 重建 Newlib 来移除除 scanf() 之外的所有浮点支持(不知道为什么)。然后您可以再次使用映射文件技术来查找“禁止”格式的 I/O 函数(尽管这些函数在任何情况下都可能也使用浮点运算符函数,因此您已经间接发现了它们)。

另一种方法是使用替代的 stdio 库来覆盖 Newlib 版本。您可以使用任意数量的“微型 printf”实现。如果您 link 这样的库作为目标代码或在 link 命令中将其库列在 Newlib 之前,它将覆盖 Newlib 版本。