查看“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帮助
工具
链入页面
相关更改
特殊页面
页面信息