【问题标题】:Implementing write(), _write() or _write_r() with Newlib?用 Newlib 实现 write()、_write() 或 _write_r()?
【发布时间】:2015-11-09 00:00:46
【问题描述】:

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

当我搜索如何重定向printf()时,很多人说我需要实现_write()_write_r()。而且似乎两者都有效。

但我仍然对它们有疑问:

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

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

感谢您阅读本文。

【问题讨论】:

  • 由于标准 C 没有定义 write 函数,因此允许符合标准的程序定义自己的名为 write 的函数(或变量),而不会改变 printf 的行为方式。这意味着printf 不能使用名为write 的函数,它必须使用一个名称不允许符合程序使用的函数,例如_write
  • write() 将与open() 一起使用;它们是标准的 POSIX 类型函数。特殊文件编号 0、1、2 用于标准输入、标准输出、标准错误(通常)。您为 newlib 编写这些实现,如果文件大于 2,那么它是一些特殊文件,您必须以某种方式对其进行索引。即,open() 将指定要写入的所需文件并返回文件编号 >2。 USER 代码不得依赖这些值。但是,实施者需要定义一些东西。
  • 不是您问题的直接答案,但this printf.c 的实现很容易移植到微控制器。我已经用过几次了,除了一个警告外,从来没有遇到过问题:一些编译器会将printf优化为puts,并在此过程中破坏一切。在这种情况下,您也可以实现 puts 或将 printf 重命名为其他名称。
  • Pinetwig 在下面给出了很好的回应。我想说的重要一点:“open()”、“write()”和朋友通常是底层系统调用的薄包装器。与“printf()”(完全在 C 库中实现的复杂代码)不同,“write()”通常只是操作系统的最小 C 接口。我不确定你想弄乱它......
  • PS:这里对"reentrancy'进行了很好的讨论。需要注意的是,“重入”与“线程安全”密切相关,但它们并不相同。例如,子例程可能会调用自己(或调用嵌套函数,然后再调用它),如果它维护任何“静态”数据,就会发生坏事。一个很好的例子是"strtok()",它既不是线程安全的也不是可重入的。

标签: c gcc arm embedded newlib


【解决方案1】:

对于第一个问题,这是因为 Newlib 想要通过在名称前加下划线来 avoid name clashes(“命名空间干净版本”)。另见Why do C compilers prepend underscores to external names?

关于第二个问题,请参阅Reentrancy and Reentrant in C?。如果你有一个多线程程序在你的板上运行,并且多个线程可以调用 newlib 函数,那么你需要使用系统调用的可重入版本。如果中断处理程序可以调用 newlib 函数,您还需要使用可重入系统调用。但是,在单线程应用程序中使用可重入系统调用是完全可以的。

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

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

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 2021-09-07
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    相关资源
    最近更新 更多