首页 > 解决方案 > GCC [for ARM] 强制无浮点

问题描述

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

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

有谁知道用 GCC/newlib 做到这一点的方法,而我不必经历并手动从它选择的 C 库文件中破解东西?

标签: gccfloating-pointarmembeddedfpu

解决方案


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

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

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

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

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


推荐阅读