From 6ad0d54dcc15952c86d93371a7088ddf22173e6f Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Mon, 17 Jan 2022 17:06:25 -0500 Subject: [PATCH] =?UTF-8?q?=E7=BE=8E=E5=8C=96libc=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../programming-manual/libc/libc.md | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/rt-thread-version/rt-thread-standard/programming-manual/libc/libc.md b/rt-thread-version/rt-thread-standard/programming-manual/libc/libc.md index 0892f7d..5ce8796 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/libc/libc.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/libc/libc.md @@ -2,7 +2,7 @@ RT-Thread 提供的 Libc (C library, C库),包含编译器配平层和 POSIX 层两部分。布局如下图所示: -![libc_structure](figures/libc_structure.png) +libc_structure @@ -12,58 +12,58 @@ RT-Thread 提供的 Libc (C library, C库),包含编译器配平层和 POSIX 配平层已经提供了一些基本的 libc 函数,这些函数不需要用户额外使能,可以即刻使用。 -### 1.1 标准输出函数 (`printf` 家族) +### 1.1 标准输出函数 (printf 家族) -#### 1.1.1 `printf` 函数 +#### 1.1.1 printf 函数 -在 Keil 和 IAR 编译平台下,用户可以直接使用 `printf` 函数;在 GCC 下,需要额外使能 `RT_USING_POSIX_FS` 和 `RT_USING_POSIX_STDIO` 宏才能使用 `printf` 函数。 +在 Keil 和 IAR 编译平台下,用户可以直接使用 printf 函数;在 GCC 下,需要额外使能 `RT_USING_POSIX_FS` 和 `RT_USING_POSIX_STDIO` 宏才能使用 printf 函数。 -#### 1.1.2 `rt_kprintf` 函数 与 `printf` 函数的使用选择 +#### 1.1.2 rt_kprintf 函数 与 printf 函数的使用选择 -如果如果不是特殊需求,建议使用 `rt_kprintf` 函数,因为 `printf` 是有编译平台内部提供的,其空间占用、以及内存使用情况我们无从得知,`printf` 函数要比 `rt_kprintf` 函数的 ROM 占用大很多。 +如果如果不是特殊需求,建议使用 rt_kprintf 函数,因为 printf 是有编译平台内部提供的,其空间占用、以及内存使用情况我们无从得知,printf 函数要比 rt_kprintf 函数的 ROM 占用大很多。 -无论是 `rt_kprintf` 函数以及 `printf` 函数都是非线程函数,在多线程同时使用的情况下,会出现交叉打印的现象,该问题是正常现象,因为根据 C 标准的要求,`printf` 函数就是非线程安全的。 +无论是 rt_kprintf 函数以及 printf 函数都是非线程函数,在多线程同时使用的情况下,会出现交叉打印的现象,该问题是正常现象,因为根据 C 标准的要求,printf 函数就是非线程安全的。 -原生 `rt_kprintf` 函数是经过优化的,占用空间要比 `printf` 函数小很多。但是 `rt_kprintf` 函数并不支持浮点类型的输出。因此: +原生 rt_kprintf 函数是经过优化的,占用空间要比 printf 函数小很多。但是 rt_kprintf 函数并不支持浮点类型的输出。因此: -1. 如需 `rt_kprintf` 函数支持浮点类型的输出,可以安装 [rt_vsnprintf_full 软件包](https://github.com/mysterywolf/rt_vsnprintf_full)。 -2. 如需 `rt_kprintf` 函数支持线程安全输出,可以安装 [rt_kprintf_threadsafe 软件包](https://github.com/mysterywolf/rt_kprintf_threadsafe)。 -3. 上述两个软件包可以同时安装使用,以同时让 `rt_kprintf` 支持线程安全和浮点类型输出的能力。 +1. 如需 rt_kprintf 函数支持浮点类型的输出,可以安装 [rt_vsnprintf_full 软件包](https://github.com/mysterywolf/rt_vsnprintf_full)。 +2. 如需 rt_kprintf 函数支持线程安全输出,可以安装 [rt_kprintf_threadsafe 软件包](https://github.com/mysterywolf/rt_kprintf_threadsafe)。 +3. 上述两个软件包可以同时安装使用,以同时让 rt_kprintf 支持线程安全和浮点类型输出的能力。 -#### 1.1.3 其他字符串格式化输出函数 (例如 `snprintf` 等) +#### 1.1.3 其他字符串格式化输出函数 (例如 snprintf 等) -其他字符串格式化输出函数(例如 `snprintf` 等)都是可以直接使用的。 +其他字符串格式化输出函数(例如 snprintf 等)都是可以直接使用的。 -强烈建议用户使用 `rt_snprintf` 等 RT-Thread 这侧的函数来代替 `snprintf` 等函数以降低资源消耗。尤其是在 GCC 编译链下,Newlib(GCC 工具链内部默认的 C 库)内置提供的 `snprintf` 函数是非线程安全的,在多线程无保护输出浮点数的情况下可能会引发死机(`snprintf` 函数非线程安全是不正常的)。 +强烈建议用户使用 rt_snprintf 等 RT-Thread 这侧的函数来代替 snprintf 等函数以降低资源消耗。尤其是在 GCC 编译链下,Newlib(GCC 工具链内部默认的 C 库)内置提供的 snprintf 函数是非线程安全的,在多线程无保护输出浮点数的情况下可能会引发死机(snprintf 函数非线程安全是不正常的)。 -同理,原生 `rt_snprintf` 等函数不支持浮点输出,用户可以通过安装 [rt_vsnprintf_full 软件包](https://github.com/mysterywolf/rt_vsnprintf_full) 来支持浮点数输出。 +同理,原生 rt_snprintf 等函数不支持浮点输出,用户可以通过安装 [rt_vsnprintf_full 软件包](https://github.com/mysterywolf/rt_vsnprintf_full) 来支持浮点数输出。 ### 1.2 内存相关函数 -`malloc`、`realloc`、`calloc`、`free` 内存分配函数可以直接使用,其已经被 `rt_malloc`、`rt_calloc`、`rt_realloc`、`rt_free` 函数接管,二者无任何区别。 +malloc 、realloc 、calloc 、free 内存分配函数可以直接使用,其已经被 rt_malloc 、rt_calloc 、rt_realloc 、rt_free 函数接管,二者无任何区别。 -`memcpy`、`memset` 等内存操作相关函数。这里需要注意的时,建议使用`rt_memcpy` 以及 `rt_memset` 来代替 `memcpy` 和 `memset`,虽然`rt_memxxx` 函数要比C库的内存操作函数要慢一些,但是要更安全;除非您对拷贝速度非常在意,否则建议使用 `rt_memxxx` 函数。如果使用的是 Cortex-M 的 MCU,可以安装 [rt_memcpy_cm](https://github.com/mysterywolf/rt_memcpy_cm) 软件包来对 `rt_memcpy` 函数进行汇编加速,该软件包安全且高效。 +memcpy 、memset 等内存操作相关函数。这里需要注意的时,建议使用 rt_memcpy 以及 rt_memset 来代替 memcpy 和 memset ,虽然 rt_memxxx 函数要比C库的内存操作函数要慢一些,但是要更安全;除非您对拷贝速度非常在意,否则建议使用 rt_memxxx 函数。如果使用的是 Cortex-M 的 MCU,可以安装 [rt_memcpy_cm](https://github.com/mysterywolf/rt_memcpy_cm) 软件包来对 rt_memcpy 函数进行汇编加速,该软件包安全且高效。 ### 1.3 字符串相关函数 -`strlen` 等字符串相关函数为编译器C库内置函数,可以直接使用。 +strlen 等字符串相关函数为编译器C库内置函数,可以直接使用。 ### 1.4 系统函数 -`exit`、`abort` 函数,调用后相当于删除当前线程。 +exit 、abort 函数,调用后相当于删除当前线程。 -`system` 函数可以用于在 C 程序中内置执行一些 Finish 命令。 +system 函数可以用于在 C 程序中内置执行一些 Finish 命令。 ### 1.5 时间函数 -所有 ANSI/ISO-C 规定的时间函数均可以使用,例如 `time`、`ctime` 等函数。注意:部分涉及到获取当前时间的函数需要使能 RTC 设备才可以正常工作,如果没有使能 RTC 设备就调用这些函数,会在串口终端给出警告。 +所有 ANSI/ISO-C 规定的时间函数均可以使用,例如 time 、ctime 等函数。注意:部分涉及到获取当前时间的函数需要使能 RTC 设备才可以正常工作,如果没有使能 RTC 设备就调用这些函数,会在串口终端给出警告。 -支持时区功能,可以通过 `RT_LIBC_DEFAULT_TIMEZONE` 宏定义设置默认时区,默认的时区为 UTC+8 北京时间,在运行过程中也可以使用 `tz_set()`, `tz_get()`, `tz_is_dst()` 函数动态设置或获取时区相关信息(需要包含 头文件)。 +支持时区功能,可以通过 `RT_LIBC_DEFAULT_TIMEZONE` 宏定义设置默认时区,默认的时区为 UTC+8 北京时间,在运行过程中也可以使用 tz_set() 、 tz_get() 、 tz_is_dst() 函数动态设置或获取时区相关信息(需要包含 头文件)。 目前,RT-Thread的时间相关Libc函数唯一不支持的是夏令时自动转换相关功能。夏令时在中国不使用,主要是欧美国家在使用。 > [!NOTE] -> 注:时区是给人看的,不是给机器看的。因此,底层驱动不应当使用带有时区的时间,而应该使用格林威治时间,即UTC+0。当且仅当该时间需要显示出来给人看的时候,才需要临时将其使用带有时区转换功能的函数(例如`ctime`)显示时间。否则很容易引发时间上的错乱。 +> 注:时区是给人看的,不是给机器看的。因此,底层驱动不应当使用带有时区的时间,而应该使用格林威治时间,即UTC+0。当且仅当该时间需要显示出来给人看的时候,才需要临时将其使用带有时区转换功能的函数(例如 ctime)显示时间。否则很容易引发时间上的错乱。 > > 注意以下两组函数的区别,功能相同,唯一的区别是是否考虑时区问题: > @@ -75,13 +75,13 @@ RT-Thread 提供的 Libc (C library, C库),包含编译器配平层和 POSIX ### 1.6 注意事项 1. 为保证跨不同编译器、不同工具链的兼容性,建议用户应用层代码: - - 使用 `` 代替 `` - - 使用 `` 代替 `` + - 使用 代替 + - 使用 代替 ## 2. POSIX 层 #### 2.1 标准输入输出函数 -在不使能 POSIX 层相关功能的情况下,用户无法使用 `read`、`getchar` 等获取字符串输入的标准 C 函数,需要开启 `RT_USING_POSIX_FS` 和 `RT_USING_POSIX_STDIO` 宏。 +在不使能 POSIX 层相关功能的情况下,用户无法使用 read 、getchar 等获取字符串输入的标准 C 函数,需要开启 `RT_USING_POSIX_FS` 和 `RT_USING_POSIX_STDIO` 宏。 -如果已经开启 Finish 功能的话,可以在 finish 线程下,使用 `finish_getchar` 代替 `getchar`,来获取从终端键入的字符。 +如果已经开启 Finish 功能的话,可以在 finish 线程下,使用 finish_getchar 代替 getchar,来获取从终端键入的字符。 -- Gitee