查看“Newlib”的源代码
←
Newlib
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
== 源代码 == === 主要 === https://sourceware.org/git/newlib-cygwin.git == 说明 == newlib是一个用于嵌入式系统的C运行库,通常与GCC搭配使用。 常用于单片机。 == 系统调用 == 对于嵌入式系统而言,环境复杂多样,有的支持多线程有的不支持,因此部分关于OS的接口C运行库不能预先实现。 对于newlib而言,用户需要手动实现一些操作系统接口。 === 基本OS接口 === 基本OS接口用于单进程(线程)环境或者不使用OS相关特性(只要求编译通过而不使用系统调用)的场景。 实现OS接口时应当包含errno.h头文件(用于使用错误代码)。 {| class="wikitable" !名称 !类型 !说明 !备注 |- |<code>_exit</code> |函数 |退出程序并清理文件 | |- |<code>close</code> |函数 |关闭文件 |默认示例:<syntaxhighlight lang="c" line="1"> int close(int file) { return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_close_r |- |<code>environ</code> |指针 |环境变量 |默认示例:<syntaxhighlight lang="c" line="1"> char *__env[1] = { 0 }; char **environ = __env; </syntaxhighlight> |- |<code>execve</code> |函数 |将控制权交给新进程 |默认示例:<syntaxhighlight lang="c" line="1"> #include <errno.h> #undef errno extern int errno; int execve(char *name, char **argv, char **env) { errno = ENOMEM; return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_execve_r |- |<code>fork</code> |函数 |创建新进程 |默认示例:<syntaxhighlight lang="c" line="1"> #include <errno.h> #undef errno extern int errno; int fork(void) { errno = EAGAIN; return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_fork_r |- |<code>fstat</code> |函数 |获取打开的文件的状态 |默认示例:<syntaxhighlight lang="c"> #include <sys/stat.h> int fstat(int file, struct stat *st) { st->st_mode = S_IFCHR; return 0; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_fstat_r |- |<code>getpid</code> |函数 |获取进程ID |默认示例:<syntaxhighlight lang="c" line="1"> int getpid(void) { return 1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_getpid_r |- |<code>isatty</code> |函数 |查询输出流是否为终端 |默认示例:<syntaxhighlight lang="c" line="1"> int isatty(int file) { return 1; } </syntaxhighlight> |- |<code>kill</code> |函数 |发送信号 |默认示例:<syntaxhighlight lang="c" line="1"> #include <errno.h> #undef errno extern int errno; int kill(int pid, int sig) { errno = EINVAL; return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_kill_r |- |<code>link</code> |函数 |给已有文件创建一个新名字 |默认示例:<syntaxhighlight lang="c" line="1"> #include <errno.h> #undef errno extern int errno; int link(char *old, char *new) { errno = EMLINK; return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_link_r |- |<code>lseek</code> |函数 |设置文件位置 |默认示例:<syntaxhighlight lang="c" line="1"> int lseek(int file, int ptr, int dir) { return 0; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_lseek_r |- |<code>open</code> |函数 |打开文件 |默认示例:<syntaxhighlight lang="c" line="1"> int open(const char *name, int flags, int mode) { return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_open_r |- |<code>read</code> |函数 |读取文件 |默认示例:<syntaxhighlight lang="c" line="1"> int read(int file, char *ptr, int len) { return 0; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_read_r |- |<code>sbrk</code> |函数 |增大程序数据空间,默认的内存分配函数依赖此函数 |默认示例:<syntaxhighlight lang="c" line="1"> caddr_t sbrk(int incr) { extern char _end; /* Defined by the linker */ static char *heap_end; char *prev_heap_end; if (heap_end == 0) { heap_end = &_end; } prev_heap_end = heap_end; if (heap_end + incr > stack_ptr) { write (1, "Heap and stack collision\n", 25); abort (); } heap_end += incr; return (caddr_t) prev_heap_end; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_sbrk_r |- |<code>stat</code> |函数 |获取文件状态 |默认示例:<syntaxhighlight lang="c" line="1"> int stat(char *file, struct stat *st) { st->st_mode = S_IFCHR; return 0; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_stat_r |- |<code>times</code> |函数 |当前进程时间信息 |默认示例:<syntaxhighlight lang="c" line="1"> int times(struct tms *buf) { return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_times_r |- |<code>unlink</code> |函数 |移除文件的目录入口,相当于删除 |默认示例:<syntaxhighlight lang="c" line="1"> #include <errno.h> #undef errno extern int errno; int unlink(char *name) { errno = ENOENT; return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_unlink_r |- |<code>wait</code> |函数 |等待子进程 |默认示例:<syntaxhighlight lang="c" line="1"> #include <errno.h> #undef errno extern int errno; int wait(int *status) { errno = ECHILD; return -1; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_wait_r |- |<code>write</code> |函数 |写入数据到文件 |默认示例:<syntaxhighlight lang="c" line="1"> int write(int file, char *ptr, int len) { int todo; for (todo = 0; todo < len; todo++) { outbyte (*ptr++); } return len; } </syntaxhighlight>可重入版本(用于多进程(线程)环境):_write_r |} === 可重入OS接口 === 可重入OS接口用于多进程(线程)环境。 newlib的可重入实现在reent.h头文件中,可重入结构体定义为<samp><code>struct _reent</code>,未启用<code>_REENT_THREAD_LOCAL</code>宏定义时实现可重入的要求如下:</samp> * 每一个进程(线程)都必须有一个可重入结构体变量,并且在创建进程(线程)时初始化,删除进程(线程)时清理。个人推荐将可重入结构体附加到PCB(进程控制块)上。 * 在调用相关库函数时将全局变量 <code>_impure_ptr</code> 改成当前进程(线程)的独有的可重入结构体变量指针或者启用<code>__DYNAMIC_REENT__</code>手动实现<code>struct _reent * __getreent (void);</code>函数。个人推荐在线程上下文切换时进行修改变量操作或者手动实现<code>__getreent</code>函数(对于多核CPU而言,只能手动实现<code>__getreent</code>,直接返回当前CPU的运行线程的可重入结构体变量指针)。 当启用<code>_REENT_THREAD_LOCAL</code> 宏定义时,可重入的实现由线程局部(TLS)变量实现,无需可重入结构体,调用可重入函数时<samp><code>struct _reent</code> 的指针为NULL</samp>。 {| class="wikitable" !函数 !声明 |- |_close_r |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _close_r(struct _reent *ptr, int fd); </syntaxhighlight> |- |<code>_execve_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _execve_r(struct _reent *ptr, const char *name,char *const argv[], char *const env[]); </syntaxhighlight> |- |<code>_fork_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _fork_r(struct _reent *ptr); </syntaxhighlight> |- |<code>_wait_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _wait_r(struct _reent *ptr, int *status); </syntaxhighlight> |- |<code>_fstat_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _fstat_r(struct _reent *ptr,int fd, struct stat *pstat); </syntaxhighlight> |- |<code>_link_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _link_r(struct _reent *ptr,const char *old, const char *new); </syntaxhighlight> |- |<code>_lseek_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> off_t _lseek_r(struct _reent *ptr,int fd, off_t pos, int whence); </syntaxhighlight> |- |<code>_open_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _open_r(struct _reent *ptr,const char *file, int flags, int mode); </syntaxhighlight> |- |<code>_read_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> _ssize_t _read_r(struct _reent *ptr,int fd, void *buf, size_t cnt); </syntaxhighlight> |- |<code>_sbrk_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr); </syntaxhighlight> |- |<code>_kill_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _kill_r(struct _reent *ptr, int pid, int sig); </syntaxhighlight> |- |<code>_getpid_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _getpid_r(struct _reent *ptr); </syntaxhighlight> |- |<code>_stat_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _stat_r(struct _reent *ptr,const char *file, struct stat *pstat); </syntaxhighlight> |- |<code>_times_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> #include <sys/times.h> clock_t _times_r(struct _reent *ptr, struct tms *ptms); </syntaxhighlight> |- |<code>_unlink_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> int _unlink_r(struct _reent *ptr, const char *file); </syntaxhighlight> |- |<code>_write_r</code> |<syntaxhighlight lang="c" line="1"> #include <reent.h> _ssize_t _write_r(struct _reent *ptr,int fd, const void *buf, size_t cnt); </syntaxhighlight> |} == 内存管理 == 对于C语言而言,内存管理主要指动态内存分配与释放。 对于newlib而言,主要的内存管理函数如下: {| class="wikitable" !函数 !可重入版本 !备注 |- |<code>void *malloc(size_t <var>nbytes</var>);</code> |<code>void *_malloc_r(void *<var>reent</var>, size_t <var>nbytes</var>);</code> |常用函数 |- |<code>void *realloc(void *<var>aptr</var>, size_t <var>nbytes</var>);</code> |<code>void *_realloc_r(void *<var>reent</var>, void *<var>aptr</var>, size_t <var>nbytes</var>);</code> | |- |<code>void *reallocf(void *<var>aptr</var>, size_t <var>nbytes</var>);</code> |<code>void *_reallocf_r(void *<var>reent</var>, void *<var>aptr</var>, size_t <var>nbytes</var>);</code> | |- |<code>void free(void *<var>aptr</var>);</code> |<code>void _free_r(void *<var>reent</var>, void *<var>aptr</var>);</code> |常用函数 |- |<code>void *memalign(size_t <var>align</var>, size_t <var>nbytes</var>);</code> |<code>void *_memalign_r(void *<var>reent</var>, size_t <var>align</var>, size_t <var>nbytes</var>);</code> | |- |<code>size_t malloc_usable_size(void *<var>aptr</var>);</code> |<code>size_t _malloc_usable_size_r(void *<var>reent</var>, void *<var>aptr</var>);</code> | |} 对于有些RTOS而言,它们有自己的内存分配机制,通常直接重写malloc与free函数而不使用newlib自身的内存分配机制。 newlib的内存分配依靠sbrk(或_sbrk_r)实现,对于单线程环境而言,无需其它操作,对于多线程环境而言,需要给内存分配与释放加锁,需要手工实现以下内存分配锁: {| class="wikitable" !函数 !说明 |- |<code>void __malloc_lock (struct _reent *<var>reent</var>);</code> |malloc锁 |- |<code>void __malloc_unlock (struct _reent *<var>reent</var>);</code> |malloc解锁 |} 注意:内存分配锁中不能调用内存分配相关函数,尽量使用静态变量。内存分配锁应当具有递归锁的特点,即同一线程可多次加锁后解锁相同次数才解锁。 == 官方资料 == 网站: http://sourceware.org/newlib/ === 相关数据手册 === * [[文件:Newlib Libc.pdf|居中|缩略图|libc]] * [[文件:Newlib Libm.pdf|居中|缩略图|libm]] == 相关资料 == * picolibc:https://github.com/picolibc/picolibc
返回至“
Newlib
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
变体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息