使用 Newlib 实现 write()、_write() 或 _write_r()?

Implementing write(), _write() or _write_r() with Newlib?

我正在尝试在 ARM GCC 工具链环境中为 STM32F411RET 微控制器重定向 printf() 函数,该环境使用标准 C 库的 Newlib。

当我搜索如何重新定位 printf() 时,许多人说我需要实施 _write()_write_r()。它似乎都有效。

但我对它们仍有疑问:

  1. 当我查看 document of Newlib 时,它说我可以实现 write() 来输出文件,但它看起来不起作用。看起来我们可以实现 _write() 但文档中从未提及此功能。 write() 怎么了?下划线有什么不同吗?

  2. 在什么情况下 _write_r()_wirte() 更可取?我不明白 C 中可重入的概念。有例子吗?

感谢阅读本文。

第一个问题,因为Newlib要avoid name clashes ("namespace clean versions") by prepending an underscore to the name. See also Why do C compilers prepend underscores to external names?

第二个问题见。如果你的开发板上有一个多线程程序 运行,并且多个线程可以调用 newlib 函数,那么你需要使用系统调用的可重入版本。如果中断处理程序可以调用 newlib 函数,您还需要使用可重入系统调用。但是,在单线程应用程序中使用可重入系统调用是完全可以的。

例如,如果您在多线程应用程序中使用不可重入系统调用,则只有一个全局错误标志。如果在两个或多个线程中发生错误,则可以覆盖全局 errno 值。在可重入系统调用中,每个线程都有自己的 errno-flag(在 _reent-struct - see here 中实现)。因此,每个线程都可以检查并处理自己的错误。

注意:您必须将 newlib 重新编译为 select 您想要使用的系统调用模型。参见 http://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html#sec_configure_host