Newlib库是一个复杂的标准C库,包括字符串支持,浮点运算,内存分配(malloc),和I/O流函数(printf,fprinf(),等等)。Newlib有两个组件构成:libc提供了主要的c语言库的实现,而libm提供了浮点运算支持。
为什么要为Newlib费心呢?如果你正在写一个非常小的嵌入式系统,你可能有自己的C标准库的子集。但是如果你要求很多的基本函数,那么一个现存的库能够帮你跳过大量的工作而使你集中力量在真正的任务上。这就是Newlib的价值,你可以从Newlib中的得到100,000多行的预先写好的经过测试的库代码。
尽管Newlib 提供了复杂的函数集,你不用担心它胀满你的ROM。代码是非常模块化的,所以你的目标代码连接器将在需要的时候从库中调用相应的功能。
Newlib库的发布是源代码级的,你在嵌入式应用中使用它前需要交叉编译生成二进制库。由于主要使用GNU GCC交叉编译器工具链,所以使用GCC配置和生成二进制库是一个简单的处理过程。你也可以使用非GCC工具,但需要更多的手工配置。
Newlib 包括了从各种资源中收集来的代码,多个免费软件授权的分发也反映了其起源的多样性。基本上它有一个嵌入式系统开发者所喜爱的像BSD一样的非限制性授权。允许你不需要公开你的源代码来使用该库。你可以从newlib home page 得到更详细的信息。
Newlib依赖于少量的系统调用例程,你必须对依赖于系统的任务提供处理,特别是I/O支持。例如,你调用了printf()函数,Newlib库负责创建一个格式化的字符串,但是不知道在那里或如何显示它。因此它需要调用_write系统例程来执行最后输出。
int _write(int handle, char *ptr, size_t len);
当调用printf()的时候,”handle”将被保留其中”1”意味着stdout标准输出,”ptr” 指向包含格式化字符串的缓冲区,”len”将是格式化字符串的长度。你的_write()系统调用例程的实现是通过一个串行调试端口发送缓冲区内容到一个远端的调试终端上显示出来。
下面是Newlib可能需要的系统调用例程的列表。不要被这个列表吓住:很少需要你来实现所有这些调用。而且经常是返回-1来指示一个错误或者一个合适的伪结果。
实现系统调用例程的最简单方法是按照需要来实现。直接使用Newlib库,直到目标代码连接器警告一个库函数缺少了一个系统调用函数再去实现它。通过这样的方法,你就不会为那些你的系统不需要的系统调用浪费时间了。
接下来,我们来看一下 Newlib库中的文件流I/O函数,并且讨论在一个实时操作系统环境中使用Newlib库的重进入和多线程问题。