C - gcc-arm-none-eabi 11.3"未实现,将始终失败"



我正在进行一个裸机STM32项目,在Linux x64主机上进行编译。

在将我的工具链从gcc-arm-none-eabi-11.2-2022.02升级到arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi后,我收到以下链接器警告:

warning: _close is not implemented and will always fail
warning: _fstat is not implemented and will always fail
warning: _getpid is not implemented and will always fail
warning: _isatty is not implemented and will always fail
warning: _kill is not implemented and will always fail
warning: _lseek is not implemented and will always fail
warning: _open is not implemented and will always fail
warning: _read is not implemented and will always fail
warning: _write is not implemented and will always fail

更全面地说,我得到了这个:

~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-closer.o): in function `_close_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/closer.c:47: warning: _close is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-fstatr.o): in function `_fstat_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/fstatr.c:55: warning: _fstat is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-signalr.o): in function `_getpid_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/signalr.c:83: warning: _getpid is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-isattyr.o): in function `_isatty_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/isattyr.c:52: warning: _isatty is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-signalr.o): in function `_kill_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/signalr.c:53: warning: _kill is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-lseekr.o): in function `_lseek_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/lseekr.c:49: warning: _lseek is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-openr.o): in function `_open_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/openr.c:50: warning: _open is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-readr.o): in function `_read_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/readr.c:49: warning: _read is not implemented and will always fail
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-writer.o): in function `_write_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/writer.c:49: warning: _write is not implemented and will always fail

除此之外,这个项目似乎编译得很好。阅读发布说明(此处提供),我看不出是什么原因导致了这种情况。

  1. 是什么变化导致了这种情况
  2. 我可以无视这些警告吗?它看起来像是系统调用,所以我想我可以吗
  3. 如果是这样,他们能被噤声吗

gcc-arm-none-eabi提供的库称为"newlib"。您可以从下载副本git://sourceware.org/git/newlib-cygwin.git.它有标记,您可以确定编译器发布的特定版本,并获得标记的版本。

例如,syscalls.c就是一种实现。Libc存根文档包含要实现的函数。然而,你可能会想知道为什么你会收到这些警告。有各种"C"库函数调用,如srand()assert()等,它们将在"C"文件库中拖动。如果您希望最小化开销,则需要查看映射文件并避免这些函数调用。

我不确定你的代码库和地图文件的子部分是否会有帮助。给你,

  • _open_r
  • _关闭_r
  • _读取(_r)

它们来自可重入库的"重入"。通常,只有RTOS或桌面操作系统才需要重新进入功能。如果你有一个裸露的金属单主线程,你不需要这些功能。您不能使用以下选项在中断处理程序中调用open():)因此,实际上只有一个上下文(以及一个errno)。"重新进入"功能是无用的。按照.fini部分,嵌入式设备不会正常"关闭",而是重新启动。

是什么变化导致了这种情况?

您链接了一些东西(称为函数),这些东西在"C"库中引入了文件系统基元。

我可以忽略这些警告吗?

这取决于您的用例。你是一个安全关键系统吗?一般来说,我建议修复它们,这样下一个人就不会感到困惑。如果代码遵循这些函数的路径,则很可能存在错误/未处理的情况。

它看起来像是系统调用,所以我想我可以吗?

不是问题吗?

如果是,他们能被噤声吗?

要么避免函数,要么提供"做正确事情"的替代实现。"正确的事情"将取决于您的平台。

以下是出现链接器错误时的选项列表。

  1. 更改构建选项
  2. 提供图书馆
  3. 提供一个备用库
  4. 避免函数调用/数据使用

您可以实现自己的close_r()open_r()read_r()。例如,可以使用带有链接blob的嵌入式只读文件系统(选项3)。最有可能的是写入stderr,因此可能不合适(选项4)。备选案文2实际上是本案的问题;但这可能很好。。。只是newlib的作者不确定什么是正确的,因此发出了警告。

您遇到的警告被放置在libnosys的syscalls实现中(例如,请参阅close.c和相关的warning.h。在某个时刻,你可以通过链接到libnosys

  • -lnosys链接标志(在Makefiles中常见,由STM32CubeMX生成)
  • --specs=nosys.specs编译/链接标志

开发人员使用了一个巧妙的技巧将警告消息嵌入到对象文件中,使用.gnu.warning.SYMBOL_NAME-很遗憾,我找不到官方文档,但您可以在此处和此处阅读更多信息。

您看到这些警告的原因是这些系统调用被引用为"某处">。。。它可能是代码中的一个杂散printf/putchar、exit()、rand()或libc本身的一些用法。

关于警告的严重性

在独立的裸机环境中,使用伪系统调用是绝对正常的,因为我们不希望与操作系统交互。如果您在平台上使用RTOS,可能会有一个专用的系统调用实现在等待您。因此,这个警告可能没有什么可担心的。我认为警告信息本身有点误导——;失败";它的意思是";什么也不做并返回错误状态";,这是定义明确的行为,不应导致异常程序执行。

附带说明:我检查了10-200-q4-major版本的libnosys.a,它没有那些警告符号。

最后,如何消除这些信息

正如其他人提到的,在独立环境中,您可以提供自己的伪系统调用,并且不与libnosys链接。我搜索了ld文档和源代码,没有找到一个链接器选项来抑制这个警告。

请注意,如果您依赖于使用C中的malloc或C++中的new的动态内存分配,则_sbrk的实现必须实际工作(此处提供更多信息),否则您可能会输入"调试非常有趣,它持续了几个星期;区

有趣的是,libnosys对_sbrk的实现是有效的,并且没有嵌入警告符号。我强烈建议使用它,除非你需要在外部RAM等上分配堆。

使用libnosys的另一个好处是,您不需要在所做的每个项目中都在中编写自定义系统调用,这可能会令人厌烦且容易出错。

TL;DR

话虽如此,实际上有一种方法可以永久消除libnosys的警告:在工具链目录中查找libnosys.a(在arm-none abi的情况下,每个体系结构和浮动abi都有一个),并使用从存档中删除.gnu.warning符号

arm-none-eabi-objcopy -w -R .gnu.warning.* libnosys.a

请注意,这将不可逆地修改您的工具链文件。很可能是有意的、无害的方式,但仍然如此。小心使用。

如果您使用CMake来构建您的项目,我会考虑创建PRE_LINK命令,该命令复制相关的libnosys,去掉它的警告,并与它链接。

这些是系统调用需要实现的方法,您使用标准库(NEWLIB)的函数,因此您应该根据自己的平台来实现这些方法如果您确定不需要实现这些,只需在链接中添加一个空的实现添加链接

void _close(void)
{
}
void _lseek(void)
{
}
void _read(void)
{
}
void _write(void)
{
}

之前

[ 50%] Building C object CMakeFiles/xpad.dir/src/main.c.o
[100%] Linking C executable xpad
/home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: /home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/libc.a(libc_a-closer.o): in function `_close_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/closer.c:47: warning: _close is not implemented and will always fail
/home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: /home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/libc.a(libc_a-lseekr.o): in function `_lseek_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/lseekr.c:49: warning: _lseek is not implemented and will always fail
/home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: /home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/libc.a(libc_a-readr.o): in function `_read_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/readr.c:49: warning: _read is not implemented and will always fail
/home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: /home/wangkai/workspace/xpad/toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/libc.a(libc_a-writer.o): in function `_write_r':
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/writer.c:49: warning: _write is not implemented and will always fail
[100%] Built target xpad

之后

[ 33%] Building C object CMakeFiles/xpad.dir/src/system_call.c.o
[ 66%] Linking C executable xpad
[100%] Built target xpad

当我更新STM32CubeIDE(基于Eclipse)时,也发生了同样的事情。这是因为更新了GNU工具链。

转到项目的属性,C/C++构建,设置,打开工具链管理器,然后安装一个比当前工具链旧的工具链。完成后,使用您刚刚安装的GNU工具链,问题应该会消失。

在此处输入图像描述

最新更新