在Newlib中,您没有实现 printf() 包含在库中。您只需实现一组最小的系统调用来支持该库。流设备sycalls API包括 open , close , read 和 write (或带有。的可重入版本 _r 后缀) - 如果你使用多线程并且需要每个线程,那么这里的重入是有用的 errno (在任何实施特定的重新入职要求中)。
printf()
open
close
read
write
_r
errno
如果您正在实施的是 stdout (使用的流 printf() , putchar() , puts() 并且只支持单个设备(通常是UART)并且不关心重定向或重入的能力,然后 open , close 和 read 可以是空的,而且 write 可以直接将提供的缓冲区直接输出到您的低级串行I / O API:
stdout
putchar()
puts()
int _write(int handle, char *data, int size ) { int count ; handle = handle ; // unused for( count = 0; count < size; count++) { outputByte( data[count] ) ; // Your low-level output function here. } return count; }
注意 handle 这里没用。对于 stdout 它将是1( stdin = 0和 stderr = 2)。该 handle 如果你想要单独的输出设备,将使用参数 stdout 和 stderr 或者如果您支持其他设备或文件系统 fopen 要么 stdout 重定向。它用于识别由其打开的蒸汽 open 。通过忽略它的所有流输出(例如 fprintf() 将以相同的方式处理并输出到同一设备);在许多情况下(在哪里 printf() 只是获取调试输出的一种方法,或者您的应用程序没有您不关心的文件系统。
handle
stdin
stderr
fopen
fprintf()
鉴于 write 功能, printf() 将“正常工作”(以最简单的方式),因为在引擎盖下所有stdio输出函数调用 write )。建议使用缓冲且无阻塞的低电平输出功能(例如,中断驱动的UART驱动器)。
显然,如果你想接受 输入 上 stdin 你也会实现类似的 read 功能。
如果你想要一堆( malloc() 等)你还需要实现 sbrk / sbrk_r 。我建议你至少在Newlib系统调用中实现它。
malloc()
sbrk
sbrk_r
Bill Gaitliff在其中讨论了对系统调用实施的更复杂的处理方法 在嵌入式系统中移植和使用Newlib ,同时讨论基本实现 这里 虽然提供了类似于上面的示例最小实现存根 Newlib文档 本身。