diff --git a/include/arch/mr_hw_irq.h b/include/arch/mr_hw_irq.h index ed540e1..4e8ecbd 100644 --- a/include/arch/mr_hw_irq.h +++ b/include/arch/mr_hw_irq.h @@ -24,6 +24,9 @@ * @brief This function saves the current interrupt mask. * * @return The current interrupt mask. + * + * @note User implementation. + * @note Need to clear the hardware interrupt mask. */ int mr_hw_irq_save(void); @@ -31,6 +34,8 @@ int mr_hw_irq_save(void); * @brief This function restores the interrupt mask. * * @param mask The interrupt mask to restore. + * + * @note User implementation. */ void mr_hw_irq_restore(int mask); diff --git a/include/kernel/kos/mr_kos.h b/include/kernel/kos/mr_kos.h index 1cdcaf2..92d6449 100644 --- a/include/kernel/kos/mr_kos.h +++ b/include/kernel/kos/mr_kos.h @@ -9,8 +9,11 @@ #ifndef __MR_KOS_H__ #define __MR_KOS_H__ +#include +#if defined(MR_USE_KOS) #include #include +#endif /* defined(MR_USE_KOS) */ #ifdef __cplusplus extern "C" { @@ -21,6 +24,7 @@ extern "C" { * @{ */ +#if defined(MR_USE_KOS) /* Kthread operations type */ typedef struct mr_kthread_ops { mr_err_t (*init)(void *res, const char *name, void *kth, void *stack, @@ -86,14 +90,7 @@ MR_INLINE void mr_kos_put(mr_kos_t *kos) { * @return The kernel os. */ mr_kos_t *mr_kos_find(void); - -/** - * @brief This macro function gets the kthread operations of a kernel os. - * - * @param _kos The kernel os. - * @return The kthread operations of the kernel os. - */ -#define MR_KOS_KTH_OPS(_kos) ((_kos)->type->kth_type->ops) +#endif /* defined(MR_USE_KOS) */ /** @} */ diff --git a/include/kernel/kos/mr_kthread.h b/include/kernel/kos/mr_kthread.h index c5e22b6..ebe0635 100644 --- a/include/kernel/kos/mr_kthread.h +++ b/include/kernel/kos/mr_kthread.h @@ -9,7 +9,10 @@ #ifndef __MR_KTHREAD_H__ #define __MR_KTHREAD_H__ +#include +#if defined(MR_USE_KOS) #include +#endif /* defined(MR_USE_KOS) */ #ifdef __cplusplus extern "C" { @@ -20,6 +23,7 @@ extern "C" { * @{ */ +#if defined(MR_USE_KOS) /* Kthread type */ typedef struct mr_kthread { mr_kobject_t parent; @@ -144,6 +148,30 @@ mr_err_t mr_kthread_exit(mr_kthread_t *kth); */ mr_kthread_t *mr_kthread_self(void); +/** + * @brief This function cleanup a kthread. + * + * @param kth The kthread. + */ +void mr_kthread_cleanup(mr_kthread_t *kth); + +/** + * @brief This function is the kthread entry. + * + * @param kth The kthread. + * + * @note User does not need to call this function. + */ +void mr_kthread_entry(mr_kthread_t *kth); + +/** + * @brief This function find a kthread. + * + * @param name The kthread name. + * @return The kthread on success, or MR_NULL on failure. + */ +mr_kthread_t *mr_kthread_find(const char *name); + /** * @brief This function get a kthread. * @@ -162,30 +190,7 @@ MR_INLINE mr_kthread_t *mr_kthread_get(mr_kthread_t *kth) { MR_INLINE void mr_kthread_put(mr_kthread_t *kth) { mr_kobject_put((mr_kobject_t *)kth); } - -/** - * @brief This function find a kthread. - * - * @param name The kthread name. - * @return The kthread on success, or MR_NULL on failure. - */ -mr_kthread_t *mr_kthread_find(const char *name); - -/** - * @brief This function cleanup a kthread. - * - * @param kth The kthread. - */ -void mr_kthread_cleanup(mr_kthread_t *kth); - -/** - * @brief This function is the kthread entry. - * - * @param kth The kthread. - * - * @note User does not need to call this function. - */ -void mr_kthread_entry(mr_kthread_t *kth); +#endif /* defined(MR_USE_KOS) */ /** @} */ diff --git a/include/kernel/mr_kfifo.h b/include/kernel/mr_kfifo.h deleted file mode 100644 index 0937a34..0000000 --- a/include/kernel/mr_kfifo.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @copyright (c) 2024, MacRsh - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2024-09-06 MacRsh First version - */ - -#ifndef __MR_KFIFO_H__ -#define __MR_KFIFO_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * @addtogroup Kfifo - * @{ - */ - -/* Kfifo type */ -typedef struct mr_kfifo { - mr_uint8_t *buf; - mr_uint32_t size; - mr_uint32_t in; - mr_uint32_t out; -} mr_kfifo_t; - -/** - * @brief This function initializes a kfifo. - * - * @param kfifo The kfifo to initialize. - * @param buf The buffer of the kfifo. - * @param size The size of the kfifo. - */ -void mr_kfifo_init(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size); - -/** - * @brief This function puts data into a kfifo. - * - * @param kfifo The kfifo to put data into. - * @param buf The data to put into the kfifo. - * @param size The size of the data. - * @return The number of bytes put into the kfifo. - */ -mr_uint32_t mr_kfifo_in(mr_kfifo_t *kfifo, const void *buf, mr_uint32_t size); - -/** - * @brief This function takes data out of a kfifo. - * - * @param kfifo The kfifo to take data out of. - * @param buf The data to take out of the kfifo. - * @param size The size of the data. - * @return The number of bytes taken out of the kfifo. - */ -mr_uint32_t mr_kfifo_out(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size); - -/** - * @brief This function puts data into a kfifo, overwriting old data. - * - * @param kfifo The kfifo to put data into. - * @param buf The data to put into the kfifo. - * @param size The size of the data. - * @return The number of bytes put into the kfifo. - */ -mr_uint32_t mr_kfifo_in_overwrite(mr_kfifo_t *kfifo, const void *buf, - mr_uint32_t size); - -/** - * @brief This function peeks data out of a kfifo. - * - * @param kfifo The kfifo to peek data out of. - * @param buf The data to peek out of the kfifo. - * @param size The size of the data. - * @return The number of bytes peeked out of the kfifo. - */ -mr_uint32_t mr_kfifo_peek(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size); - -/** - * @brief This function gets the size of a kfifo. - * - * @param kfifo The kfifo to get the size of. - * @return The size of the kfifo. - */ -MR_INLINE mr_uint32_t mr_kfifo_size(mr_kfifo_t *kfifo) { - return kfifo->size; -} - -/** - * @brief This function gets the number of available space bytes in a kfifo. - * - * @param kfifo The kfifo to get the number of available space bytes in. - * @return The number of available space bytes in the kfifo. - */ -MR_INLINE mr_uint32_t mr_kfifo_avail(mr_kfifo_t *kfifo) { - return kfifo->size - (kfifo->in - kfifo->out); -} - -/** - * @brief This function gets the number of data bytes in a kfifo. - * - * @param kfifo The kfifo to get the number of data bytes in. - * @return The number of data bytes in the kfifo. - */ -MR_INLINE mr_uint32_t mr_kfifo_len(mr_kfifo_t *kfifo) { - return kfifo->in - kfifo->out; -} - -/** - * @brief This function resets a kfifo. - * - * @param kfifo The kfifo to reset. - */ -MR_INLINE void mr_kfifo_reset(mr_kfifo_t *kfifo) { - kfifo->in = kfifo->out = 0; -} - -/** - * @brief This function skips data in a kfifo. - * - * @param kfifo The kfifo to skip data in. - * @param size The size of the data to skip. - * @return The number of bytes skipped. - */ -MR_INLINE mr_uint32_t mr_kfifo_skip(mr_kfifo_t *kfifo, mr_uint32_t size) { - kfifo->out += MR_MIN(size, mr_kfifo_len(kfifo)); - return size; -} - -/** - * @brief This function checks if a kfifo is empty. - * - * @param kfifo The kfifo to check. - * @return MR_TRUE if the kfifo is empty, MR_FALSE otherwise. - */ -MR_INLINE mr_bool_t mr_kfifo_is_empty(mr_kfifo_t *kfifo) { - return (kfifo->in == kfifo->out) ? MR_TRUE : MR_FALSE; -} - -/** - * @brief This function checks if a kfifo is full. - * - * @param kfifo The kfifo to check. - * @return MR_TRUE if the kfifo is full, MR_FALSE otherwise. - */ -MR_INLINE mr_bool_t mr_kfifo_is_full(mr_kfifo_t *kfifo) { - return (kfifo->in == (kfifo->out + kfifo->size)) ? MR_TRUE : MR_FALSE; -} - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MR_KFIFO_H__ */ diff --git a/include/kernel/mr_kmap.h b/include/kernel/mr_kmap.h deleted file mode 100644 index 0586663..0000000 --- a/include/kernel/mr_kmap.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @copyright (c) 2024, MacRsh - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2024-09-06 MacRsh First version - */ - -#ifndef __MR_KMAP_H__ -#define __MR_KMAP_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * @addtogroup Kmap - * @{ - */ - -/* Knode type */ -typedef struct mr_knode { - struct mr_knode *next; - mr_uint32_t key; - void *value; -} mr_knode_t; - -/* Kmap type */ -typedef struct mr_kmap { - mr_knode_t **b; - mr_size_t size; - mr_size_t count; - mr_f32_t load_factor; -} mr_kmap_t; - -/** - * @brief This function initializes a kmap. - * - * @param kmap The kmap to initialize. - * @param size The size of the kmap. - * @param load_factor The load factor of the kmap. - * @return 0 on success, or a negative error code on failure. - */ -mr_err_t mr_kmap_init(mr_kmap_t *kmap, mr_size_t size, mr_f32_t load_factor); - -/** - * @brief This function adds a key-value pair to the kmap. - * - * @param kmap The kmap to add the key-value pair to. - * @param key The key to add. - * @param value The value to add. - * @return 0 on success, or a negative error code on failure. - */ -mr_err_t mr_kmap_add(mr_kmap_t *kmap, mr_uint32_t key, void *value); - -/** - * @brief This function deletes a key-value pair from the kmap. - * - * @param kmap The kmap to delete the key-value pair from. - * @param key The key to delete. - * @return The value of the deleted key-value pair, or MR_NULL if not found. - */ -void *mr_kmap_del(mr_kmap_t *kmap, mr_uint32_t key); - -/** - * @brief This function gets the value of a key from the kmap. - * - * @param kmap The kmap to get the value from. - * @param key The key to get the value of. - * @return The value of the key, or MR_NULL if not found. - */ -void *mr_kmap_value(mr_kmap_t *kmap, mr_uint32_t key); - -/** - * @brief This function clears the kmap. - * - * @param kmap The kmap to clear. - */ -void mr_kmap_clear(mr_kmap_t *kmap); - -/** - * @brief This function shrinks the kmap. - * - * @param kmap The kmap to shrink. - * @param size The new size of the kmap. - * @return 0 on success, or a negative error code on failure. - */ -mr_err_t mr_kmap_shrink(mr_kmap_t *kmap, mr_size_t size); - -/** - * @brief This function gets the size of the kmap. - * - * @param kmap The kmap to get the size of. - * @return The size of the kmap. - */ -MR_INLINE mr_size_t mr_kmap_count(mr_kmap_t *kmap) { - return kmap->count; -} - -/** - * @brief This function checks if the kmap is empty. - * - * @param kmap The kmap to check. - * @return MR_TRUE if the kmap is empty, MR_FALSE otherwise. - */ -MR_INLINE mr_bool_t mr_kmap_is_empty(mr_kmap_t *kmap) { - return (kmap->count == 0) ? MR_TRUE : MR_FALSE; -} - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MR_KMAP_H__ */ diff --git a/include/kernel/mr_kobject.h b/include/kernel/mr_kobject.h index 97859bd..d796fba 100644 --- a/include/kernel/mr_kobject.h +++ b/include/kernel/mr_kobject.h @@ -44,7 +44,7 @@ typedef struct mr_kobject { mr_uint32_t magic; mr_kname_t name; #if !defined(MR_CFG_KOBJECT_INAME_SIZE) -#define MR_CFG_KOBJECT_INAME_SIZE (16) +#define MR_CFG_KOBJECT_INAME_SIZE (8) #endif /* !defined(MR_CFG_KOBJECT_INAME_SIZE) */ char iname[MR_CFG_KOBJECT_INAME_SIZE]; struct mr_kobject *parent; diff --git a/include/kernel/mr_kslist.h b/include/kernel/mr_kslist.h deleted file mode 100644 index 1130558..0000000 --- a/include/kernel/mr_kslist.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @copyright (c) 2024, MacRsh - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2024-09-06 MacRsh First version - */ - -#ifndef __MR_KSLIST_H__ -#define __MR_KSLIST_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * @addtogroup Kslist - * @{ - */ - -/* Single list type */ -typedef struct mr_kslist { - struct mr_kslist *next; -} mr_kslist_t; - -/** - * @brief This macro function initializes a single list. - * - * @param _kslist The list to initialize. - */ -#define MR_KSLIST_INIT(_kslist) \ - { .next = MR_NULL } - -/** - * @brief This function initializes a single list. - * - * @param entry The element to initialize. - */ -MR_INLINE void mr_kslist_init(mr_kslist_t *entry) { - entry->next = MR_NULL; -} - -/** - * @brief This function adds an element to the list. - * - * @param head The list head. - * @param entry The element to add. - * - * @note Adds to the end of the list. - */ -MR_INLINE void mr_kslist_add(mr_kslist_t *head, mr_kslist_t *entry) { - mr_kslist_t *p; - - p = head; - while (!p->next) { - p = p->next; - } - p->next = entry; -} - -/** - * @brief This function inserts an element into the list. - * - * @param head The list head. - * @param entry The element to insert. - * - * @note Inserts to the beginning of the list. - */ -MR_INLINE void mr_kslist_insert(mr_kslist_t *head, mr_kslist_t *entry) { - entry->next = head->next; - head->next = entry; -} - -/** - * @brief This function removes an element from the list. - * - * @param head The list head. - * @param entry The element to remove. - */ -MR_INLINE void mr_kslist_del(mr_kslist_t *head, mr_kslist_t *entry) { - mr_kslist_t *p; - - p = head; - while (!p->next) { - if (p->next != entry) { - p = p->next; - continue; - } - p->next = entry->next; - entry->next = MR_NULL; - return; - } -} - -/** - * @brief This function checks if the list is empty. - * - * @param head The list head. - * @return MR_TRUE on empty, MR_FALSE otherwise. - */ -MR_INLINE mr_bool_t mr_kslist_is_empty(mr_kslist_t *head) { - return (!head->next) ? MR_TRUE : MR_FALSE; -} - -/** - * @brief This macro function iterates through the list. - * - * @param _pos The pointer to the element. - * @param _head The list head. - */ -#define MR_KSLIST_FOR_EACH(_pos, _head) \ - for ((_pos) = (_head)->next; (_pos) != MR_NULL; (_pos) = (_pos)->next) - -/** - * @brief This macro function iterates through the list in safe order. - * - * @param _pos The pointer to the element. - * @param _n The pointer to the next element. - * @param _head The list head. - */ -#define MR_KSLIST_FOR_EACH_SAFE(_pos, _n, _head) \ - for ((_pos) = (_head)->next, (_n) = (_pos) ? (_pos)->next : MR_NULL; \ - (_pos) != MR_NULL; \ - (_pos) = (_n), (_n) = (_pos) ? (_pos)->next : MR_NULL) - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MR_KSLIST_H__ */ diff --git a/include/kernel/mr_ktimer.h b/include/kernel/mr_ktimer.h index 2e594d2..af6ec22 100644 --- a/include/kernel/mr_ktimer.h +++ b/include/kernel/mr_ktimer.h @@ -9,8 +9,11 @@ #ifndef __MR_KTIMER_H__ #define __MR_KTIMER_H__ +#include +#if defined(MR_USE_KTIMER) #include #include +#endif /* defined(MR_USE_KTIMER) */ #ifdef __cplusplus extern "C" { @@ -21,8 +24,9 @@ extern "C" { * @{ */ +#if defined(MR_USE_KTIMER) /* Periodic definition */ -#define MR_KTIMER_PERIODIC (1U << 31) +#define MR_KTIMER_PERIODIC (1U << 31) /* Ktimer type */ typedef struct mr_ktimer { @@ -96,6 +100,34 @@ mr_err_t mr_ktimer_stop(mr_ktimer_t *ktimer); */ mr_err_t mr_ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick); +/** + * @brief This function find a ktimer. + * + * @param name The ktimer name. + * @return The ktimer on success, or MR_NULL on failure. + */ +mr_ktimer_t *mr_ktimer_find(const char *name); + +/** + * @brief This function get a ktimer. + * + * @param ktimer The ktimer. + * @return The ktimer on success, or MR_NULL on failure. + */ +MR_INLINE mr_ktimer_t *mr_ktimer_get(mr_ktimer_t *ktimer) { + return (mr_ktimer_t *)mr_kobject_get((mr_kobject_t *)ktimer); +} + +/** + * @brief This function put a ktimer. + * + * @param ktimer The ktimer. + */ +MR_INLINE void mr_ktimer_put(mr_ktimer_t *ktimer) { + mr_kobject_put((mr_kobject_t *)ktimer); +} +#endif /* defined(MR_USE_KTIMER) */ + /** @} */ #ifdef __cplusplus diff --git a/include/libc/mr_atomic.h b/include/libc/mr_atomic.h index c04d5ae..f0f19fe 100644 --- a/include/libc/mr_atomic.h +++ b/include/libc/mr_atomic.h @@ -13,7 +13,7 @@ #include #if !defined(__CC_ARM) && !defined(__GNUC__) && !defined(__clang__) #include -#endif /* defined(__CC_ARM) || defined(__GNUC__) || defined(__clang__) */ +#endif /* !defined(__CC_ARM) && !defined(__GNUC__) && !defined(__clang__) */ #ifdef __cplusplus extern "C" { diff --git a/include/libc/mr_stdio.h b/include/libc/mr_stdio.h deleted file mode 100644 index b576b1a..0000000 --- a/include/libc/mr_stdio.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @copyright (c) 2024, MacRsh - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2024-09-06 MacRsh First version - */ - -#ifndef __MR_STDIO_H__ -#define __MR_STDIO_H__ - -#include -#if defined(MR_USE_LIBC_STDIO) -#include -#else -#include -#endif /* defined(MR_USE_LIBC_STDIO) */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * @addtogroup Stdio - * @{ - */ - -/* Stdio definition */ -#if defined(MR_USE_LIBC_STDIO) -#define mr_vprintf(_f, _a) vprintf(_f, _a) -#define mr_vsnprintf(_b, _s, _f, _a) vsnprintf(_b, _s, _f, _a) -#else - -#endif /* defined(MR_USE_LIBC_STDIO) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MR_STDIO_H__ */ diff --git a/include/libc/mr_string.h b/include/libc/mr_string.h index e971519..74bca18 100644 --- a/include/libc/mr_string.h +++ b/include/libc/mr_string.h @@ -126,6 +126,15 @@ char *mr_strerror(int errnum); */ mr_size_t mr_strlen(const char *s); +/** + * @brief This function returns the length of the string. + * + * @param s The string. + * @param size The maximum length of the string. + * @return The length of the string. + */ +mr_size_t mr_strnlen(const char *s, mr_size_t size); + /** * @brief This function compares the first size bytes of s1 and s2. * diff --git a/include/libc/mr_types.h b/include/libc/mr_types.h index 3474ed3..c8c0a11 100644 --- a/include/libc/mr_types.h +++ b/include/libc/mr_types.h @@ -10,12 +10,12 @@ #define __MR_TYPES_H__ #include -#ifdef MR_USE_LIBC_TYPES +#if defined(MR_USE_LIBC_TYPES) #include #include #include #include -#endif /* MR_USE_LIBC_TYPES */ +#endif /* defined(MR_USE_LIBC_TYPES) */ #ifdef __cplusplus extern "C" { @@ -27,7 +27,7 @@ extern "C" { */ /* Signed integer type */ -#ifdef MR_USE_LIBC_TYPES +#if defined(MR_USE_LIBC_TYPES) typedef int8_t mr_int8_t; typedef int16_t mr_int16_t; typedef int32_t mr_int32_t; @@ -41,21 +41,18 @@ typedef signed char mr_int8_t; typedef signed short mr_int16_t; typedef signed int mr_int32_t; typedef signed long long mr_int64_t; -typedef long long mr_ssize_t; #define MR_INT8_MAX (127) #define MR_INT16_MAX (32767) #define MR_INT32_MAX (2147483647U) #define MR_INT64_MAX (9223372036854775807LL) -#endif /* MR_USE_LIBC_TYPES */ +#endif /* defined(MR_USE_LIBC_TYPES) */ /* Unsigned integer type */ -#ifdef MR_USE_LIBC_TYPES +#if defined(MR_USE_LIBC_TYPES) typedef uint8_t mr_uint8_t; typedef uint16_t mr_uint16_t; typedef uint32_t mr_uint32_t; typedef uint64_t mr_uint64_t; -typedef size_t mr_size_t; -typedef long mr_ssize_t; #define MR_UINT8_MAX UINT8_MAX #define MR_UINT16_MAX UINT16_MAX #define MR_UINT32_MAX UINT32_MAX @@ -65,15 +62,28 @@ typedef unsigned char mr_uint8_t; typedef unsigned short mr_uint16_t; typedef unsigned int mr_uint32_t; typedef unsigned long long mr_uint64_t; -typedef unsigned long long mr_size_t; #define MR_UINT8_MAX (255) #define MR_UINT16_MAX (65535) #define MR_UINT32_MAX (4294967295) #define MR_UINT64_MAX (18446744073709551615ULL) -#endif /* MR_USE_LIBC_TYPES */ +#endif /* defined(MR_USE_LIBC_TYPES) */ + +/* Size type */ +#if defined(MR_USE_LIBC_TYPES) +typedef size_t mr_size_t; +typedef ssize_t mr_ssize_t; +#else +#if defined(MR_USE_ARCH_64BIT) +typedef unsigned long long mr_size_t; +typedef long long mr_ssize_t; +#else +typedef unsigned int mr_size_t; +typedef int mr_ssize_t; +#endif /* defined(MR_USE_ARCH_64BIT) */ +#endif /* defined(MR_USE_ARCH_64BIT) */ /* Boolean type */ -#ifdef MR_USE_LIBC_TYPES +#if defined(MR_USE_LIBC_TYPES) typedef bool mr_bool_t; #define MR_FALSE false #define MR_TRUE true @@ -81,42 +91,40 @@ typedef bool mr_bool_t; typedef int mr_bool_t; #define MR_FALSE (0) #define MR_TRUE (1) -#endif /* MR_USE_LIBC_TYPES */ +#endif /* defined(MR_USE_LIBC_TYPES) */ /* Pointer type */ -#ifdef MR_USE_LIBC_TYPES +#if defined(MR_USE_LIBC_TYPES) typedef void * mr_ptr_t; typedef intptr_t mr_intptr_t; typedef uintptr_t mr_uintptr_t; #define MR_NULL NULL #else typedef void * mr_ptr_t; -typedef long long mr_intptr_t; -typedef unsigned long long mr_uintptr_t; +typedef mr_ssize_t mr_intptr_t; +typedef mr_size_t mr_uintptr_t; #define MR_NULL ((void *)0) -#endif /* MR_USE_LIBC_TYPES */ +#endif /* defined(MR_USE_LIBC_TYPES) */ /* Floating point type */ typedef float mr_f32_t; typedef double mr_f64_t; /* Variable argument list type */ -#ifdef MR_USE_LIBC_TYPES +#if defined(MR_USE_LIBC_TYPES) typedef va_list mr_va_list; -#define mr_va_start(_ap, _n) va_start(_ap, _n) -#define mr_va_arg(_ap, _t) va_arg(_ap, _t) -#define mr_va_end(_ap) va_end(_ap) +#define mr_va_start(_a, _l) va_start(_a, _l) +#define mr_va_arg(_a, _t) va_arg(_a, _t) +#define mr_va_end(_a) va_end(_a) #else typedef char * mr_va_list; -#define __mr_va_rounded_size(_t) \ - (((sizeof(_t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) -#define mr_va_start(_ap, _n) \ - ((_ap) = (char *)&(_n) + __mr_va_rounded_size(_n)) -#define mr_va_arg(_ap, _type) \ - ((_ap) += __mr_va_rounded_size(_type), \ - *((_type *)((_ap)-__mr_va_rounded_size(_type)))) -#define mr_va_end(_ap) ((_ap) = (mr_va_list)0) -#endif /* MR_USE_LIBC_TYPES */ +#define mr_va_start(_a, _l) ((_a) = (mr_va_list)&(_l) + sizeof(_l)) +#define __mr_va_align(_p, _t) \ + ((mr_va_list)(((mr_size_t)(_p) + sizeof(_t) - 1) & ~(sizeof(_t) - 1))) +#define mr_va_arg(_a, _t) \ + ((_a) = __mr_va_align(_a, _t) + sizeof(_t), *(_t *)((_a) - sizeof(_t))) +#define mr_va_end(_a) ((_a) = (mr_va_list)0) +#endif /* defined(MR_USE_LIBC_TYPES) */ /** @} */ diff --git a/include/mr_config.h b/include/mr_config.h index f29da08..75e8706 100644 --- a/include/mr_config.h +++ b/include/mr_config.h @@ -5,9 +5,6 @@ extern "C" { #endif /* __cplusplus */ -#define MR_USE_LIBC_PRINTF -//#define MR_USE_LIBC_MALLOC - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/kernel/kclock.c b/kernel/kclock.c index d6abc57..0c5c75a 100644 --- a/kernel/kclock.c +++ b/kernel/kclock.c @@ -17,7 +17,9 @@ static mr_atomic_t kclock; #if defined(MR_USE_THREAD) && (MR_CFG_KCLOCK_HOOK_SIZE < 2) #error "If use thread, clock hook size must >= 2" #endif /* defined(MR_USE_THREAD) && (MR_CFG_KCLOCK_HOOK_SIZE < 2) */ +/* Clock hook entry */ static mr_ptr_t kentry[MR_CFG_KCLOCK_HOOK_SIZE]; +/* Clock hook */ static mr_khook_t khook = MR_KHOOK_INIT(kentry, MR_CFG_KCLOCK_HOOK_SIZE); MR_INLINE void kclock_hook(void) { diff --git a/kernel/kfifo.c b/kernel/kfifo.c deleted file mode 100644 index abd736b..0000000 --- a/kernel/kfifo.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @copyright (c) 2024, MacRsh - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2024-09-06 MacRsh First version - */ - -#include -#include - -MR_INLINE mr_uint32_t kfifo_align_down_pow2(mr_uint32_t val) { - if (val == 0) { - return 0; - } - val |= val >> 1; - val |= val >> 2; - val |= val >> 4; - val |= val >> 8; - val |= val >> 16; - return val - (val >> 1); -} - -void mr_kfifo_init(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size) { - kfifo->buf = buf; - kfifo->in = 0; - kfifo->out = 0; - - /* Align 2^n(down) */ - kfifo->size = kfifo_align_down_pow2(size); -} - -mr_uint32_t mr_kfifo_in(mr_kfifo_t *kfifo, const void *buf, mr_uint32_t size) { - mr_uint32_t s; - - /* Get available size */ - size = MR_MIN(size, mr_kfifo_avail(kfifo)); - if (size == 0) { - return 0; - } - - /* In end of kfifo */ - s = MR_MIN(size, kfifo->size - (kfifo->in & (kfifo->size - 1))); - mr_memcpy(kfifo->buf + (kfifo->in & (kfifo->size - 1)), buf, s); - - /* In start of kfifo */ - mr_memcpy(kfifo->buf, (mr_uint8_t *)buf + s, size - s); - - /* Update in index */ - kfifo->in += size; - return size; -} - -mr_uint32_t mr_kfifo_out(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size) { - /* Peek kfifo */ - size = mr_kfifo_peek(kfifo, buf, size); - - /* Update out index */ - kfifo->out += size; - return size; -} - -mr_uint32_t mr_kfifo_in_overwrite(mr_kfifo_t *kfifo, const void *buf, - mr_uint32_t size) { - mr_uint32_t s; - - /* Skip the useless data */ - s = MR_MIN(size, mr_kfifo_size(kfifo)); - if (s > size) { - buf = (mr_uint8_t *)buf + (size - s); - size = s; - } - - /* Give space to kfifo */ - s = mr_kfifo_avail(kfifo); - if (s < size) { - mr_kfifo_skip(kfifo, size - s); - } - - /* In kfifo */ - return mr_kfifo_in(kfifo, buf, size); -} - -mr_uint32_t mr_kfifo_peek(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size) { - mr_uint32_t s; - - /* Get available size */ - size = MR_MIN(size, mr_kfifo_len(kfifo)); - if (size == 0) { - return 0; - } - - /* Out end of kfifo */ - s = MR_MIN(size, kfifo->size - (kfifo->out & (kfifo->size - 1))); - mr_memcpy(buf, kfifo->buf + (kfifo->out & (kfifo->size - 1)), s); - - /* Out start of kfifo */ - mr_memcpy((mr_uint8_t *)buf + s, kfifo->buf, size - s); - return size; -} diff --git a/kernel/kmap.c b/kernel/kmap.c deleted file mode 100644 index 4dabe65..0000000 --- a/kernel/kmap.c +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @copyright (c) 2024, MacRsh - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2024-09-06 MacRsh First version - */ - -#include -#include -#include - -mr_err_t mr_kmap_init(mr_kmap_t *kmap, mr_size_t size, mr_f32_t load_factor) { - /* Check arguments */ - if ((size == 0) || (load_factor <= 0.0f) || (load_factor > 1.0f)) { - return -MR_EINVAL; - } - - /* Initialize kmap */ - kmap->b = mr_calloc(size, sizeof(mr_knode_t)); - if (!kmap->b) { - return -MR_ENOMEM; - } - kmap->size = size; - kmap->count = 0; - kmap->load_factor = load_factor; - return 0; -} - -MR_INLINE mr_err_t kmap_resize(mr_kmap_t *kmap, mr_size_t new_size) { - mr_knode_t *node, *prev; - mr_knode_t **new_b; - mr_size_t index, i; - - if (new_size == kmap->size) { - /* No need to resize */ - return 0; - } - - /* Allocate new bucket */ - if (new_size > 0) { - new_b = mr_calloc(new_size, sizeof(mr_knode_t)); - if (!new_b) { - return -MR_ENOMEM; - } - - /* Rehash */ - for (i = 0; i < kmap->size; i++) { - node = kmap->b[i]; - while (node) { - prev = node; - node = node->next; - index = prev->key % new_size; - prev->next = new_b[index]; - new_b[index] = prev; - } - } - } else { - new_b = MR_NULL; - } - - /* Update kmap */ - mr_free(kmap->b); - kmap->b = new_b; - kmap->size = new_size; - return 0; -} - -mr_err_t mr_kmap_add(mr_kmap_t *kmap, mr_uint32_t key, void *value) { - mr_knode_t *node; - mr_size_t index; - mr_err_t ret; - - /* Check arguments */ - if ((kmap->size == 0) || (!value)) { - return -MR_EINVAL; - } - - /* Check load factor */ - if (((mr_f32_t)kmap->count / (mr_f32_t)kmap->size) >= kmap->load_factor) { - /* Resize kmap */ - ret = kmap_resize(kmap, kmap->size * 2); - if (ret != 0) { - return ret; - } - } - - /* Update existing node */ - index = key % kmap->size; - node = kmap->b[index]; - while (node) { - if (node->key != key) { - node = node->next; - continue; - } - - /* Update value */ - node->value = value; - return 0; - } - - /* Insert new node */ - node = mr_malloc(sizeof(mr_knode_t)); - if (!node) { - return -MR_ENOMEM; - } - node->next = kmap->b[index]; - node->key = key; - node->value = value; - kmap->b[index] = node; - kmap->count++; - return 0; -} - -void *mr_kmap_del(mr_kmap_t *kmap, mr_uint32_t key) { - mr_knode_t *node, *prev; - mr_size_t index; - void *value; - - /* Check arguments */ - if (kmap->size == 0) { - return MR_NULL; - } - - /* Remove node */ - index = key % kmap->size; - node = kmap->b[index]; - prev = MR_NULL; - while (node) { - if (node->key != key) { - prev = node; - node = node->next; - continue; - } - if (!prev) { - kmap->b[index] = node->next; - } else { - prev->next = node->next; - } - value = node->value; - mr_free(node); - kmap->count--; - - /* Check shrink factor */ - if (((((mr_f32_t)kmap->size * kmap->load_factor) / 4.0f) - > (mr_f32_t)kmap->count)) { - /* Resize kmap */ - kmap_resize(kmap, kmap->size / 2); - } - return value; - } - return MR_NULL; -} - -void *mr_kmap_value(mr_kmap_t *kmap, mr_uint32_t key) { - mr_knode_t *node; - mr_size_t index; - - /* Check arguments */ - if (kmap->size == 0) { - return MR_NULL; - } - - /* Find node */ - index = key % kmap->size; - node = kmap->b[index]; - while (node) { - if (node->key != key) { - node = node->next; - continue; - } - return node->value; - } - return MR_NULL; -} - -void mr_kmap_clear(mr_kmap_t *kmap) { - mr_knode_t *node, *prev; - mr_size_t i; - - /* Clear kmap */ - for (i = 0; i < kmap->size; i++) { - node = kmap->b[i]; - while (node) { - prev = node; - node = node->next; - mr_free(prev); - } - kmap->b[i] = MR_NULL; - } - kmap->count = 0; -} - -mr_err_t mr_kmap_shrink(mr_kmap_t *kmap, mr_size_t size) { - /* Check arguments */ - if (size < kmap->count) { - return -MR_EINVAL; - } - - /* Resize kmap */ - return kmap_resize(kmap, size); -} diff --git a/kernel/kobject.c b/kernel/kobject.c index 72038de..39fdb1b 100644 --- a/kernel/kobject.c +++ b/kernel/kobject.c @@ -12,14 +12,15 @@ #include #include +/* Kobject lock */ +static mr_kspinlock_t klock = MR_KSPINLOCK_INIT(); +/* Kobject kset */ +static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL); + /* Last-word definition */ #define LWORD_DOT (0x2e) #define LWORD_DOT2 (0x2e2e) -/* Root kset */ -static mr_kspinlock_t klock = MR_KSPINLOCK_INIT(); -static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL); - void mr_ktype_init(mr_ktype_t *type, void (*release)(mr_kobject_t *kobj)) { /* Check arguments */ if (!type) { diff --git a/kernel/kos/kos.c b/kernel/kos/kos.c index 9a85c66..779835d 100644 --- a/kernel/kos/kos.c +++ b/kernel/kos/kos.c @@ -7,7 +7,9 @@ */ #include +#if defined(MR_USE_KOS) +/* Kos */ static mr_kos_t kroot; MR_INLINE void kos_init(mr_kos_t *os, mr_kos_type_t *ktype) { @@ -41,3 +43,4 @@ mr_kos_t *mr_kos_find(void) { /* Find kos in kroot */ return &kroot; } +#endif /* defined(MR_USE_KOS) */ diff --git a/kernel/kos/kthread.c b/kernel/kos/kthread.c index 6a0574a..1baf2e2 100644 --- a/kernel/kos/kthread.c +++ b/kernel/kos/kthread.c @@ -7,13 +7,19 @@ */ #include +#if defined(MR_USE_KOS) #include #include #include +/* Kthread ktype */ static mr_ktype_t ktype1, ktype2; +/* Kthread kset */ static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL); +/* Kthread ops macro */ +#define KOS_KTHREAD_OPS(_kos) ((_kos)->type->kth_type->ops) + MR_INLINE mr_err_t kthread_res_alloc(mr_kthread_t *kth, mr_size_t size) { void *res; @@ -70,8 +76,8 @@ MR_INLINE mr_err_t kthread_init(mr_kthread_t *kth, const char *name, } /* Init kthread resource */ - ret = MR_KOS_KTH_OPS(kos)->init((void *)kth->res, name, kth, stack, - stack_size, priority, tick); + ret = KOS_KTHREAD_OPS(kos)->init((void *)kth->res, name, kth, stack, + stack_size, priority, tick); if (ret != 0) { kthread_res_free(kth); return ret; @@ -94,7 +100,7 @@ MR_INLINE mr_err_t kthread_del(mr_kthread_t *kth) { } /* Delete kthread resource */ - return MR_KOS_KTH_OPS(kth->os)->del((void *)kth->res); + return KOS_KTHREAD_OPS(kth->os)->del((void *)kth->res); } MR_INLINE mr_err_t kthread_init_add(mr_kthread_t *kth, mr_ktype_t *ktype, @@ -237,7 +243,7 @@ MR_INLINE mr_err_t kthread_startup(mr_kthread_t *kth) { mr_kthread_get(kth); /* Startup kthread resource */ - ret = MR_KOS_KTH_OPS(kth->os)->startup((void *)kth->res); + ret = KOS_KTHREAD_OPS(kth->os)->startup((void *)kth->res); if (ret != 0) { mr_kthread_put(kth); return ret; @@ -257,7 +263,7 @@ mr_err_t mr_kthread_startup(mr_kthread_t *kth) { MR_INLINE mr_err_t kthread_resume(mr_kthread_t *kth) { /* Resume kthread resource */ - return MR_KOS_KTH_OPS(kth->os)->resume((void *)kth->res); + return KOS_KTHREAD_OPS(kth->os)->resume((void *)kth->res); } mr_err_t mr_kthread_resume(mr_kthread_t *kth) { @@ -281,7 +287,7 @@ MR_INLINE mr_err_t kthread_yield(void) { } /* Yield kthread resource */ - ret = MR_KOS_KTH_OPS(kos)->yield(); + ret = KOS_KTHREAD_OPS(kos)->yield(); /* Put kos */ mr_kos_put(kos); @@ -295,7 +301,7 @@ mr_err_t mr_kthread_yield(void) { MR_INLINE mr_err_t kthread_suspend(mr_kthread_t *kth) { /* Suspend kthread resource */ - return MR_KOS_KTH_OPS(kth->os)->suspend((void *)kth->res); + return KOS_KTHREAD_OPS(kth->os)->suspend((void *)kth->res); } mr_err_t mr_kthread_suspend(mr_kthread_t *kth) { @@ -319,7 +325,7 @@ MR_INLINE mr_err_t kthread_sleep(mr_tick_t tick) { } /* Sleep kthread resource */ - ret = MR_KOS_KTH_OPS(kos)->sleep(tick); + ret = KOS_KTHREAD_OPS(kos)->sleep(tick); /* Put kos */ mr_kos_put(kos); @@ -333,7 +339,7 @@ mr_err_t mr_kthread_sleep(mr_tick_t tick) { MR_INLINE mr_err_t kthread_exit(mr_kthread_t *kth) { /* Exit kthread resource */ - return MR_KOS_KTH_OPS(kth->os)->exit((void *)kth->res); + return KOS_KTHREAD_OPS(kth->os)->exit((void *)kth->res); } mr_err_t mr_kthread_exit(mr_kthread_t *kth) { @@ -357,7 +363,7 @@ MR_INLINE mr_kthread_t *kthread_self(void) { } /* Get kthread self */ - ret = MR_KOS_KTH_OPS(kos)->self(); + ret = KOS_KTHREAD_OPS(kos)->self(); /* Put kos */ mr_kos_put(kos); @@ -369,11 +375,6 @@ mr_kthread_t *mr_kthread_self(void) { return kthread_self(); } -mr_kthread_t *mr_kthread_find(const char *name) { - /* Lookup kthread in kroot */ - return (mr_kthread_t *)mr_kobject_lookup((mr_kobject_t *)&kroot, name); -} - void mr_kthread_cleanup(mr_kthread_t *kth) { /* Check arguments */ if ((!kth) || (!MR_KOBJECT_IS_INITED(kth))) { @@ -385,8 +386,8 @@ void mr_kthread_cleanup(mr_kthread_t *kth) { } void mr_kthread_entry(mr_kthread_t *kth) { - /* Check entry */ - if (!kth->entry) { + /* Check arguments */ + if ((!kth) || (!MR_KOBJECT_IS_INITED(kth)) || (!kth->entry)) { return; } @@ -394,6 +395,11 @@ void mr_kthread_entry(mr_kthread_t *kth) { ((void (*)(mr_kthread_t *, void *))kth->entry)(kth, kth->args); } +mr_kthread_t *mr_kthread_find(const char *name) { + /* Lookup kthread in kroot */ + return (mr_kthread_t *)mr_kobject_lookup((mr_kobject_t *)&kroot, name); +} + MR_INLINE mr_kthread_t *kthread_release_kobj(mr_kobject_t *kobj) { mr_kthread_t *kth; @@ -416,7 +422,7 @@ MR_INLINE void kthread_release1_kobj(mr_kobject_t *kobj) { MR_INLINE void kthread_release2_kobj(mr_kobject_t *kobj) { mr_kthread_t *kth; - /* Release kobject */ + /* Release kthread */ kth = kthread_release_kobj(kobj); /* Free kthread */ @@ -432,3 +438,4 @@ MR_INLINE void mr_kthread_kset_init(void) { mr_ktype_init(&ktype2, kthread_release2_kobj); } MR_INIT_EXPORT(mr_kthread_kset_init, MR_INIT_LEVEL_KERNEL); +#endif /* defined(MR_USE_KOS) */ diff --git a/kernel/ktimer.c b/kernel/ktimer.c index 6d02866..e4f7cc2 100644 --- a/kernel/ktimer.c +++ b/kernel/ktimer.c @@ -6,15 +6,20 @@ * @date 2024-09-06 MacRsh First version */ +#include +#if defined(MR_USE_KTIMER) #include #include -#include #include +/* Ktimer ktype */ static mr_ktype_t ktype1, ktype2; -static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL); +/* Ktimer list */ static mr_klist_t klist = MR_KLIST_INIT(&klist); +/* Ktimer lock */ static mr_kspinlock_t klock = MR_KSPINLOCK_INIT(); +/* Ktimer kset */ +static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL); MR_INLINE void ktimer_init(mr_ktimer_t *ktimer, mr_ptr_t entry, void *args, mr_tick_t tick) { @@ -84,14 +89,11 @@ MR_INLINE void ktimer_del(mr_ktimer_t *ktimer) { /* Lock */ mask = mr_kspinlock_lock_irqsave(&klock); - /* Already deleted */ - if (mr_klist_is_empty(&ktimer->list)) { - goto _exit; + /* Remove ktimer from ktimer list */ + if (!mr_klist_is_empty(&ktimer->list)) { + mr_klist_del(&ktimer->list); } - /* Remove ktimer from ktimer list */ - mr_klist_del(&ktimer->list); -_exit: /* Unlock */ mr_kspinlock_unlock_irqrestore(&klock, mask); } @@ -176,6 +178,11 @@ MR_INLINE void ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick) { /* Lock */ mask = mr_kspinlock_lock_irqsave(&klock); + /* Remove ktimer from ktimer list */ + if (!mr_klist_is_empty(&ktimer->list)) { + mr_klist_del(&ktimer->list); + } + /* Set init tick */ ktimer->init_tick = tick; @@ -189,15 +196,17 @@ mr_err_t mr_ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick) { return -MR_EINVAL; } - /* Delete ktimer */ - ktimer_del(ktimer); - /* Set ktimer tick */ ktimer_tick_set(ktimer, tick); return 0; } -MR_INLINE void ktimer_release1_kobj(mr_kobject_t *kobj) { +mr_ktimer_t *mr_ktimer_find(const char *name) { + /* Lookup ktimer in kroot */ + return (mr_ktimer_t *)mr_kobject_lookup((mr_kobject_t *)&kroot, name); +} + +MR_INLINE mr_ktimer_t *ktimer_release_kobj(mr_kobject_t *kobj) { mr_ktimer_t *ktimer; /* Get ktimer */ @@ -205,16 +214,19 @@ MR_INLINE void ktimer_release1_kobj(mr_kobject_t *kobj) { /* Delete ktimer */ ktimer_del(ktimer); + return ktimer; +} + +MR_INLINE void ktimer_release1_kobj(mr_kobject_t *kobj) { + /* Release ktimer */ + ktimer_release_kobj(kobj); } MR_INLINE void ktimer_release2_kobj(mr_kobject_t *kobj) { mr_ktimer_t *ktimer; - /* Get ktimer */ - ktimer = MR_CONTAINER_OF(kobj, mr_ktimer_t, parent); - - /* Delete ktimer */ - ktimer_del(ktimer); + /* Release ktimer */ + ktimer = ktimer_release_kobj(kobj); /* Free ktimer */ mr_free(ktimer); @@ -223,9 +235,11 @@ MR_INLINE void ktimer_release2_kobj(mr_kobject_t *kobj) { MR_INLINE void ktimer_timeout_check(void) { mr_ktimer_t *ktimer; mr_klist_t list; - mr_tick_t tick; int mask; + /* Operation list */ + mr_klist_init(&list); + /* Lock */ mask = mr_kspinlock_lock_irqsave(&klock); @@ -233,15 +247,13 @@ MR_INLINE void ktimer_timeout_check(void) { while (!mr_klist_is_empty(&klist)) { ktimer = MR_KLIST_ENTRY(klist.next, mr_ktimer_t, list); - /* Get current tick */ - tick = mr_kclock_tick(); - if ((tick - ktimer->timeout_tick) >= (MR_TICK_MAX / 2)) { + /* Check timeout tick */ + if ((mr_kclock_tick() - ktimer->timeout_tick) >= (MR_TICK_MAX / 2)) { /* There will be no timeout ktimer after that */ break; } /* Move ktimer into operation list */ - mr_klist_init(&list); mr_klist_move(&ktimer->list, &list); /* Unlock */ @@ -288,3 +300,4 @@ MR_INLINE void mr_ktimer_kset_init(void) { mr_kclock_hook_add(ktimer_timeout_check); } MR_INIT_EXPORT(mr_ktimer_kset_init, MR_INIT_LEVEL_KERNEL); +#endif /* defined(MR_USE_KTIMER) */ diff --git a/libc/malloc.c b/libc/malloc.c index f2c1301..71bcb64 100644 --- a/libc/malloc.c +++ b/libc/malloc.c @@ -9,15 +9,16 @@ #include #if (!defined(MR_USE_LIBC_MALLOC)) && (!defined(MR_USE_3PARTY_MALLOC)) #include -#include #if !defined(MR_CFG_HEAP_SIZE) #define MR_CFG_HEAP_SIZE (4 * 1024) #endif /* !defined(MR_CFG_HEAP_SIZE) */ -#if (MR_CFG_HEAP_SIZE < 16) +#if (MR_CFG_HEAP_SIZE < 24) #error "Heap size is too small(must >= 16)" #endif /* MR_CFG_HEAP_SIZE */ +/* Heap memory */ static mr_uint8_t heap[MR_CFG_HEAP_SIZE]; +/* Heap block head */ static mr_memblk_t blk_head = {.size = 1}; /* Heap magic number */ @@ -170,7 +171,8 @@ mr_size_t mr_malloc_usable_size(void *mem) { void *mr_calloc(mr_size_t num, mr_size_t size) { mr_size_t total; - void *memory; + mr_size_t i; + void *mem; /* Calculate the total size */ total = num * size; @@ -178,20 +180,23 @@ void *mr_calloc(mr_size_t num, mr_size_t size) { return MR_NULL; } - /* Allocate memory */ - memory = mr_malloc(total); - if (memory == MR_NULL) { - /* Not enough memory */ + /* Allocate mem */ + mem = mr_malloc(total); + if (mem == MR_NULL) { + /* Not enough mem */ return MR_NULL; } - /* Initialize the memory to 0 */ - mr_memset(memory, 0, total); - return memory; + /* Initialize the mem to 0 */ + for (i = 0; i < total; i++) { + ((mr_uint8_t *)mem)[i] = 0; + } + return mem; } void *mr_realloc(void *mem, mr_size_t size) { mr_size_t old_size; + mr_size_t i; void *new; /* Get the old size */ @@ -205,7 +210,9 @@ void *mr_realloc(void *mem, mr_size_t size) { } /* Copy the memory data to the new memory */ - mr_memcpy(new, mem, old_size); + for (i = 0; i < old_size; i++) { + ((mr_uint8_t *)new)[i] = ((mr_uint8_t *)mem)[i]; + } mr_free(mem); return new; } diff --git a/libc/string.c b/libc/string.c index 7de54f3..fd1b41b 100644 --- a/libc/string.c +++ b/libc/string.c @@ -126,6 +126,10 @@ char *mr_strerror(int errnum) { error = "Invalid argument"; break; } + case MR_ENOSYS: { + error = "Function not implemented"; + break; + } case MR_ETIMEDOUT: { error = "Connection timed out"; break; @@ -149,6 +153,18 @@ mr_size_t mr_strlen(const char *s) { return len; } +mr_size_t mr_strnlen(const char *s, mr_size_t size) { + mr_size_t len; + + if (!s) { + return 0; + } + for (len = 0; (len < size) && (*s != '\0'); s++) { + len++; + } + return len; +} + int mr_strncmp(const char *s1, const char *s2, mr_size_t size) { return mr_memcmp(s1, s2, size); }