From 12d74ab5756efd29862699050370c05c6e611831 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sun, 22 Sep 2024 13:28:15 -0400 Subject: [PATCH] [klibc] add kerrno.h --- include/klibc/kerrno.h | 77 ++++++++++++++++++ include/klibc/kstdio.h | 27 +++++++ include/klibc/kstring.h | 36 +++++++++ include/rtdef.h | 63 ++------------- include/rtklibc.h | 42 +--------- src/klibc/kerrno.c | 169 ++++++++++++++++++++++++++++++++++++++++ src/klibc/kstdio.c | 157 +------------------------------------ src/klibc/kstring.c | 5 +- 8 files changed, 319 insertions(+), 257 deletions(-) create mode 100644 include/klibc/kerrno.h create mode 100644 include/klibc/kstdio.h create mode 100644 include/klibc/kstring.h create mode 100644 src/klibc/kerrno.c diff --git a/include/klibc/kerrno.h b/include/klibc/kerrno.h new file mode 100644 index 0000000000..2f7699923f --- /dev/null +++ b/include/klibc/kerrno.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-09-22 Meco Man the first version + */ + +#ifndef __RT_KERRNO_H__ +#define __RT_KERRNO_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(RT_USING_LIBC) && !defined(RT_USING_NANO) +/* POSIX error code compatible */ +#define RT_EOK 0 /**< There is no error */ +#define RT_ERROR 255 /**< A generic/unknown error happens */ +#define RT_ETIMEOUT ETIMEDOUT /**< Timed out */ +#define RT_EFULL ENOSPC /**< The resource is full */ +#define RT_EEMPTY ENODATA /**< The resource is empty */ +#define RT_ENOMEM ENOMEM /**< No memory */ +#define RT_ENOSYS ENOSYS /**< Function not implemented */ +#define RT_EBUSY EBUSY /**< Busy */ +#define RT_EIO EIO /**< IO error */ +#define RT_EINTR EINTR /**< Interrupted system call */ +#define RT_EINVAL EINVAL /**< Invalid argument */ +#define RT_ENOENT ENOENT /**< No entry */ +#define RT_ENOSPC ENOSPC /**< No space left */ +#define RT_EPERM EPERM /**< Operation not permitted */ +#define RT_EFAULT EFAULT /**< Bad address */ +#define RT_ENOBUFS ENOBUFS /**< No buffer space is available */ +#define RT_ESCHEDISR 253 /**< scheduler failure in isr context */ +#define RT_ESCHEDLOCKED 252 /**< scheduler failure in critical region */ +#define RT_ETRAP 254 /**< Trap event */ +#else +#define RT_EOK 0 /**< There is no error */ +#define RT_ERROR 1 /**< A generic/unknown error happens */ +#define RT_ETIMEOUT 2 /**< Timed out */ +#define RT_EFULL 3 /**< The resource is full */ +#define RT_EEMPTY 4 /**< The resource is empty */ +#define RT_ENOMEM 5 /**< No memory */ +#define RT_ENOSYS 6 /**< Function not implemented */ +#define RT_EBUSY 7 /**< Busy */ +#define RT_EIO 8 /**< IO error */ +#define RT_EINTR 9 /**< Interrupted system call */ +#define RT_EINVAL 10 /**< Invalid argument */ +#define RT_ENOENT 11 /**< No entry */ +#define RT_ENOSPC 12 /**< No space left */ +#define RT_EPERM 13 /**< Operation not permitted */ +#define RT_ETRAP 14 /**< Trap event */ +#define RT_EFAULT 15 /**< Bad address */ +#define RT_ENOBUFS 16 /**< No buffer space is available */ +#define RT_ESCHEDISR 17 /**< scheduler failure in isr context */ +#define RT_ESCHEDLOCKED 18 /**< scheduler failure in critical region */ +#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */ + +rt_err_t rt_get_errno(void); +void rt_set_errno(rt_err_t no); +int *_rt_errno(void); +const char *rt_strerror(rt_err_t error); +#if !defined(RT_USING_NEWLIBC) && !defined(_WIN32) +#ifndef errno +#define errno *_rt_errno() +#endif +#endif /* !defined(RT_USING_NEWLIBC) && !defined(_WIN32) */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/klibc/kstdio.h b/include/klibc/kstdio.h new file mode 100644 index 0000000000..215e9a9245 --- /dev/null +++ b/include/klibc/kstdio.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-09-22 Meco Man the first version + */ + +#ifndef __RT_KSTDIO_H__ +#define __RT_KSTDIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int rt_vsprintf(char *dest, const char *format, va_list arg_ptr); +int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args); +int rt_sprintf(char *buf, const char *format, ...); +int rt_snprintf(char *buf, rt_size_t size, const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/klibc/kstring.h b/include/klibc/kstring.h new file mode 100644 index 0000000000..48fbe60091 --- /dev/null +++ b/include/klibc/kstring.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-09-22 Meco Man the first version + */ + +#ifndef __RT_KSTRING_H__ +#define __RT_KSTRING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void *rt_memset(void *src, int c, rt_ubase_t n); +void *rt_memcpy(void *dest, const void *src, rt_ubase_t n); +void *rt_memmove(void *dest, const void *src, rt_size_t n); +rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count); +char *rt_strdup(const char *s); +rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen); +char *rt_strstr(const char *str1, const char *str2); +rt_int32_t rt_strcasecmp(const char *a, const char *b); +char *rt_strcpy(char *dst, const char *src); +char *rt_strncpy(char *dest, const char *src, rt_size_t n); +rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count); +rt_int32_t rt_strcmp(const char *cs, const char *ct); +rt_size_t rt_strlen(const char *src); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/rtdef.h b/include/rtdef.h index 6985bb8f51..17dbc329b0 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -84,12 +84,11 @@ extern "C" { #define RT_VERSION_PATCH 0 /**< Patch version number (x.x.X) */ /* e.g. #if (RTTHREAD_VERSION >= RT_VERSION_CHECK(4, 1, 0) */ -#define RT_VERSION_CHECK(major, minor, revise) ((major * 10000) + (minor * 100) + revise) +#define RT_VERSION_CHECK(major, minor, revise) ((major * 10000U) + (minor * 100U) + revise) /* RT-Thread version */ #define RTTHREAD_VERSION RT_VERSION_CHECK(RT_VERSION_MAJOR, RT_VERSION_MINOR, RT_VERSION_PATCH) - /**@}*/ /* maximum value of base type */ @@ -99,10 +98,10 @@ extern "C" { #define RT_UINT32_MAX UINT32_MAX /**< Maximum number of UINT32 */ #define RT_UINT64_MAX UINT64_MAX /**< Maximum number of UINT64 */ #else -#define RT_UINT8_MAX 0xff /**< Maximum number of UINT8 */ -#define RT_UINT16_MAX 0xffff /**< Maximum number of UINT16 */ -#define RT_UINT32_MAX 0xffffffff /**< Maximum number of UINT32 */ -#define RT_UINT64_MAX 0xffffffffffffffff +#define RT_UINT8_MAX 0xFFU /**< Maximum number of UINT8 */ +#define RT_UINT16_MAX 0xFFFFU /**< Maximum number of UINT16 */ +#define RT_UINT32_MAX 0xFFFFFFFFUL /**< Maximum number of UINT32 */ +#define RT_UINT64_MAX 0xFFFFFFFFFFFFFFFFULL /**< Maximum number of UINT64 */ #endif /* RT_USING_LIBC */ #define RT_TICK_MAX RT_UINT32_MAX /**< Maximum number of tick */ @@ -238,58 +237,6 @@ typedef int (*init_fn_t)(void); #define RT_KERNEL_REALLOC(ptr, size) rt_realloc(ptr, size) #endif /* RT_KERNEL_REALLOC */ -/** - * @addtogroup Error - */ - -/**@{*/ - -/* RT-Thread error code definitions */ -#if defined(RT_USING_LIBC) && !defined(RT_USING_NANO) -/* POSIX error code compatible */ -#define RT_EOK 0 /**< There is no error */ -#define RT_ERROR 255 /**< A generic/unknown error happens */ -#define RT_ETIMEOUT ETIMEDOUT /**< Timed out */ -#define RT_EFULL ENOSPC /**< The resource is full */ -#define RT_EEMPTY ENODATA /**< The resource is empty */ -#define RT_ENOMEM ENOMEM /**< No memory */ -#define RT_ENOSYS ENOSYS /**< Function not implemented */ -#define RT_EBUSY EBUSY /**< Busy */ -#define RT_EIO EIO /**< IO error */ -#define RT_EINTR EINTR /**< Interrupted system call */ -#define RT_EINVAL EINVAL /**< Invalid argument */ -#define RT_ENOENT ENOENT /**< No entry */ -#define RT_ENOSPC ENOSPC /**< No space left */ -#define RT_EPERM EPERM /**< Operation not permitted */ -#define RT_EFAULT EFAULT /**< Bad address */ -#define RT_ENOBUFS ENOBUFS /**< No buffer space is available */ -#define RT_ESCHEDISR 253 /**< scheduler failure in isr context */ -#define RT_ESCHEDLOCKED 252 /**< scheduler failure in critical region */ -#define RT_ETRAP 254 /**< Trap event */ -#else -#define RT_EOK 0 /**< There is no error */ -#define RT_ERROR 1 /**< A generic/unknown error happens */ -#define RT_ETIMEOUT 2 /**< Timed out */ -#define RT_EFULL 3 /**< The resource is full */ -#define RT_EEMPTY 4 /**< The resource is empty */ -#define RT_ENOMEM 5 /**< No memory */ -#define RT_ENOSYS 6 /**< Function not implemented */ -#define RT_EBUSY 7 /**< Busy */ -#define RT_EIO 8 /**< IO error */ -#define RT_EINTR 9 /**< Interrupted system call */ -#define RT_EINVAL 10 /**< Invalid argument */ -#define RT_ENOENT 11 /**< No entry */ -#define RT_ENOSPC 12 /**< No space left */ -#define RT_EPERM 13 /**< Operation not permitted */ -#define RT_ETRAP 14 /**< Trap event */ -#define RT_EFAULT 15 /**< Bad address */ -#define RT_ENOBUFS 16 /**< No buffer space is available */ -#define RT_ESCHEDISR 17 /**< scheduler failure in isr context */ -#define RT_ESCHEDLOCKED 18 /**< scheduler failure in critical region */ -#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */ - -/**@}*/ - /** * @ingroup BasicDef * diff --git a/include/rtklibc.h b/include/rtklibc.h index 52fd8b9f1c..1577c20a6f 100644 --- a/include/rtklibc.h +++ b/include/rtklibc.h @@ -14,44 +14,8 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - -/* kstdio */ -int rt_vsprintf(char *dest, const char *format, va_list arg_ptr); -int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args); -int rt_sprintf(char *buf, const char *format, ...); -int rt_snprintf(char *buf, rt_size_t size, const char *format, ...); - -rt_err_t rt_get_errno(void); -void rt_set_errno(rt_err_t no); -int *_rt_errno(void); -const char *rt_strerror(rt_err_t error); -#if !defined(RT_USING_NEWLIBC) && !defined(_WIN32) -#ifndef errno -#define errno *_rt_errno() -#endif -#endif /* !defined(RT_USING_NEWLIBC) && !defined(_WIN32) */ - -/* kstring */ - -void *rt_memset(void *src, int c, rt_ubase_t n); -void *rt_memcpy(void *dest, const void *src, rt_ubase_t n); -void *rt_memmove(void *dest, const void *src, rt_size_t n); -rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count); -char *rt_strdup(const char *s); -rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen); -char *rt_strstr(const char *str1, const char *str2); -rt_int32_t rt_strcasecmp(const char *a, const char *b); -char *rt_strcpy(char *dst, const char *src); -char *rt_strncpy(char *dest, const char *src, rt_size_t n); -rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count); -rt_int32_t rt_strcmp(const char *cs, const char *ct); -rt_size_t rt_strlen(const char *src); - -#ifdef __cplusplus -} -#endif +#include "klibc/kstring.h" +#include "klibc/kstdio.h" +#include "klibc/kerrno.h" #endif /* __RT_KLIBC_H__ */ diff --git a/src/klibc/kerrno.c b/src/klibc/kerrno.c new file mode 100644 index 0000000000..4d83b133cb --- /dev/null +++ b/src/klibc/kerrno.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-09-22 Meco Man the first version + */ + +#include + +#define DBG_TAG "kernel.errno" +#ifdef RT_DEBUG_DEVICE +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_WARNING +#endif /* defined (RT_DEBUG_DEVICE) */ +#include + +/** + * @brief A global variable used to store the error code. + * + * This volatile static integer is used to store the most recent error code globally. + * Its volatile nature ensures that every read operation fetches the most current value, + * providing real-time error status across different parts of the program. + */ +static volatile int __rt_errno; + +/** + * @struct _errno_str_t + * @brief Structure for mapping error codes to corresponding error strings. + * + * This structure is used to create a mapping that associates an rt_err_t type error code + * with a corresponding error description string. + */ +struct _errno_str_t +{ + rt_err_t error; /**< Error code of type rt_err_t, representing different kinds of errors. */ + const char *str; /**< Pointer to the error description string. */ +}; + +/** + * @brief An array containing mappings of error codes to their corresponding error strings. + * + * This array uses the _errno_str_t structure to define several error codes and their + * corresponding error description strings. These mappings can be used at runtime + * to provide more readable error information. + */ +static struct _errno_str_t rt_errno_strs[] = +{ + {RT_EOK , "OK "}, /**< Operation successful. */ + {RT_ERROR , "ERROR "}, /**< General error. */ + {RT_ETIMEOUT, "ETIMOUT"}, /**< Operation timed out. */ + {RT_EFULL , "ERSFULL"}, /**< Resource is full. */ + {RT_EEMPTY , "ERSEPTY"}, /**< Resource is empty. */ + {RT_ENOMEM , "ENOMEM "}, /**< Not enough memory. */ + {RT_ENOSYS , "ENOSYS "}, /**< Function not implemented. */ + {RT_EBUSY , "EBUSY "}, /**< Resource is busy. */ + {RT_EIO , "EIO "}, /**< Input/output error. */ + {RT_EINTR , "EINTRPT"}, /**< Interrupted system call. */ + {RT_EINVAL , "EINVAL "}, /**< Invalid argument. */ + {RT_ENOENT , "ENOENT "}, /**< No such file or directory. */ + {RT_ENOSPC , "ENOSPC "}, /**< No space left on device. */ + {RT_EPERM , "EPERM "}, /**< Operation not permitted. */ + {RT_ETRAP , "ETRAP "}, /**< Trap error. */ +}; + +/** + * @brief This function return a pointer to a string that contains the + * message of error. + * + * @param error the errorno code + * @return a point to error message string + */ +const char *rt_strerror(rt_err_t error) +{ + int i = 0; + + if (error < 0) + error = -error; + + for (i = 0; i < sizeof(rt_errno_strs) / sizeof(rt_errno_strs[0]); i++) + { + if (rt_errno_strs[i].error == error) + return rt_errno_strs[i].str; + } + + return "EUNKNOW"; +} +RTM_EXPORT(rt_strerror); + +/** + * @brief This function gets the global errno for the current thread. + * + * @return errno + */ +rt_err_t rt_get_errno(void) +{ + rt_thread_t tid = RT_NULL; + + if (rt_interrupt_get_nest() != 0) + { + /* it's in interrupt context */ + return __rt_errno; + } + + tid = rt_thread_self(); + if (tid == RT_NULL) + { + return __rt_errno; + } + + return tid->error; +} +RTM_EXPORT(rt_get_errno); + +/** + * @brief This function sets the global errno for the current thread. + * + * @param error is the errno shall be set. + */ +void rt_set_errno(rt_err_t error) +{ + rt_thread_t tid = RT_NULL; + + if (rt_interrupt_get_nest() != 0) + { + /* it's in interrupt context */ + __rt_errno = error; + + return; + } + + tid = rt_thread_self(); + if (tid == RT_NULL) + { + __rt_errno = error; + + return; + } + + tid->error = error; +} +RTM_EXPORT(rt_set_errno); + +/** + * @brief This function returns the address of the current thread errno. + * + * @return The errno address. + */ +int *_rt_errno(void) +{ + rt_thread_t tid = RT_NULL; + + if (rt_interrupt_get_nest() != 0) + { + return (int *)&__rt_errno; + } + + tid = rt_thread_self(); + if (tid != RT_NULL) + { + return (int *) & (tid->error); + } + + return (int *)&__rt_errno; +} +RTM_EXPORT(_rt_errno); diff --git a/src/klibc/kstdio.c b/src/klibc/kstdio.c index 879a938b6a..7e09978d9a 100644 --- a/src/klibc/kstdio.c +++ b/src/klibc/kstdio.c @@ -8,10 +8,7 @@ * 2024-03-10 Meco Man the first version */ -#include -#include -#include -#include +#include #define DBG_TAG "kernel.stdio" #ifdef RT_DEBUG_DEVICE @@ -683,155 +680,3 @@ int rt_sprintf(char *buf, const char *format, ...) return n; } RTM_EXPORT(rt_sprintf); - -/* errno functions */ - -/** - * @brief A global variable used to store the error code. - * - * This volatile static integer is used to store the most recent error code globally. - * Its volatile nature ensures that every read operation fetches the most current value, - * providing real-time error status across different parts of the program. - */ -static volatile int __rt_errno; - -/** - * @struct _errno_str_t - * @brief Structure for mapping error codes to corresponding error strings. - * - * This structure is used to create a mapping that associates an rt_err_t type error code - * with a corresponding error description string. - */ -struct _errno_str_t -{ - rt_err_t error; /**< Error code of type rt_err_t, representing different kinds of errors. */ - const char *str; /**< Pointer to the error description string. */ -}; - -/** - * @brief An array containing mappings of error codes to their corresponding error strings. - * - * This array uses the _errno_str_t structure to define several error codes and their - * corresponding error description strings. These mappings can be used at runtime - * to provide more readable error information. - */ -static struct _errno_str_t rt_errno_strs[] = -{ - {RT_EOK , "OK "}, /**< Operation successful. */ - {RT_ERROR , "ERROR "}, /**< General error. */ - {RT_ETIMEOUT, "ETIMOUT"}, /**< Operation timed out. */ - {RT_EFULL , "ERSFULL"}, /**< Resource is full. */ - {RT_EEMPTY , "ERSEPTY"}, /**< Resource is empty. */ - {RT_ENOMEM , "ENOMEM "}, /**< Not enough memory. */ - {RT_ENOSYS , "ENOSYS "}, /**< Function not implemented. */ - {RT_EBUSY , "EBUSY "}, /**< Resource is busy. */ - {RT_EIO , "EIO "}, /**< Input/output error. */ - {RT_EINTR , "EINTRPT"}, /**< Interrupted system call. */ - {RT_EINVAL , "EINVAL "}, /**< Invalid argument. */ - {RT_ENOENT , "ENOENT "}, /**< No such file or directory. */ - {RT_ENOSPC , "ENOSPC "}, /**< No space left on device. */ - {RT_EPERM , "EPERM "}, /**< Operation not permitted. */ - {RT_ETRAP , "ETRAP "}, /**< Trap error. */ -}; - -/** - * @brief This function return a pointer to a string that contains the - * message of error. - * - * @param error the errorno code - * @return a point to error message string - */ -const char *rt_strerror(rt_err_t error) -{ - int i = 0; - - if (error < 0) - error = -error; - - for (i = 0; i < sizeof(rt_errno_strs) / sizeof(rt_errno_strs[0]); i++) - { - if (rt_errno_strs[i].error == error) - return rt_errno_strs[i].str; - } - - return "EUNKNOW"; -} -RTM_EXPORT(rt_strerror); - -/** - * @brief This function gets the global errno for the current thread. - * - * @return errno - */ -rt_err_t rt_get_errno(void) -{ - rt_thread_t tid = RT_NULL; - - if (rt_interrupt_get_nest() != 0) - { - /* it's in interrupt context */ - return __rt_errno; - } - - tid = rt_thread_self(); - if (tid == RT_NULL) - { - return __rt_errno; - } - - return tid->error; -} -RTM_EXPORT(rt_get_errno); - -/** - * @brief This function sets the global errno for the current thread. - * - * @param error is the errno shall be set. - */ -void rt_set_errno(rt_err_t error) -{ - rt_thread_t tid = RT_NULL; - - if (rt_interrupt_get_nest() != 0) - { - /* it's in interrupt context */ - __rt_errno = error; - - return; - } - - tid = rt_thread_self(); - if (tid == RT_NULL) - { - __rt_errno = error; - - return; - } - - tid->error = error; -} -RTM_EXPORT(rt_set_errno); - -/** - * @brief This function returns the address of the current thread errno. - * - * @return The errno address. - */ -int *_rt_errno(void) -{ - rt_thread_t tid = RT_NULL; - - if (rt_interrupt_get_nest() != 0) - { - return (int *)&__rt_errno; - } - - tid = rt_thread_self(); - if (tid != RT_NULL) - { - return (int *) & (tid->error); - } - - return (int *)&__rt_errno; -} -RTM_EXPORT(_rt_errno); diff --git a/src/klibc/kstring.c b/src/klibc/kstring.c index b3fb3b0029..562c3f7ccd 100644 --- a/src/klibc/kstring.c +++ b/src/klibc/kstring.c @@ -8,10 +8,7 @@ * 2024-03-10 Meco Man the first version */ -#include -#include -#include -#include +#include #ifdef RT_KLIBC_USING_STDLIB #include #endif /* RT_KLIBC_USING_STDLIB */