【发布时间】:2015-11-09 00:00:46
【问题描述】:
我正在尝试在使用 Newlib 作为标准 C 库的 ARM GCC 工具链环境中为 STM32F411RET 微控制器重新定位 printf() 函数。
当我搜索如何重定向printf()时,很多人说我需要实现_write()或_write_r()。而且似乎两者都有效。
但我仍然对它们有疑问:
当我查看document of Newlib 时,它说我可以实现
write()来输出文件,但它看起来不起作用。看起来我们可以实现_write(),但文档中从未提及此功能。write()怎么了?下划线有什么不同吗?在哪种情况下
_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()",它既不是线程安全的也不是可重入的。