feat(class): Supports determining whether it is a subclass
This change adds a new method to the class that allows checking whether a given class is a subclass of the base class. The new rule states that the private data size of the subclass must be larger than that of the base class.
This commit is contained in:
@@ -75,6 +75,7 @@ extern "C" {
|
||||
#define MR_EINVAL (-22) /**< Invalid argument */
|
||||
#define MR_ENOSYS (-38) /**< Not supported */
|
||||
#define MR_ETIMEOUT (-110) /**< Operation timed */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -209,9 +210,9 @@ typedef struct mr_class
|
||||
struct mr_class *parent; /**< Parent */
|
||||
mr_list_t list, clist; /**< List */
|
||||
mr_spinlock_t lock; /**< List lock */
|
||||
void *priv_data; /**< Private data */
|
||||
size_t priv_size; /**< Private data size */
|
||||
mr_ref_t ref_count; /**< Reference count */
|
||||
void *privdata; /**< Private data */
|
||||
size_t privsize; /**< Private data size */
|
||||
mr_ref_t refcount; /**< Reference count */
|
||||
void (*release)(struct mr_class *); /**< Release function */
|
||||
void *methods; /**< Methods */
|
||||
} mr_class_t;
|
||||
|
||||
@@ -50,15 +50,6 @@ int mr_log_printf(const char *tag, const char *fmt, ...);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @addtogroup Assert
|
||||
* @{
|
||||
*/
|
||||
|
||||
void mr_assert_handler(const char *ex, const char *tag, const char *fn, const char *file, int line);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @addtogroup Memory
|
||||
* @{
|
||||
@@ -78,17 +69,17 @@ void *mr_realloc(void *memory, size_t size);
|
||||
*/
|
||||
|
||||
int mr_fifo_init(mr_fifo_t *fifo, void *buf, size_t size);
|
||||
void mr_fifo_reset(mr_fifo_t *fifo);
|
||||
int mr_fifo_allocate(mr_fifo_t *fifo, size_t size);
|
||||
void mr_fifo_free(mr_fifo_t *fifo);
|
||||
size_t mr_fifo_used_get(const mr_fifo_t *fifo);
|
||||
size_t mr_fifo_free_get(const mr_fifo_t *fifo);
|
||||
size_t mr_fifo_size_get(const mr_fifo_t *fifo);
|
||||
void mr_fifo_reset(mr_fifo_t *fifo);
|
||||
size_t mr_fifo_peek(const mr_fifo_t *fifo, void *buf, size_t count);
|
||||
size_t mr_fifo_discard(mr_fifo_t *fifo, size_t count);
|
||||
size_t mr_fifo_read(mr_fifo_t *fifo, void *buf, size_t count);
|
||||
size_t mr_fifo_write(mr_fifo_t *fifo, const void *buf, size_t count);
|
||||
size_t mr_fifo_write_force(mr_fifo_t *fifo, const void *buf, size_t count);
|
||||
size_t mr_fifo_get_used(const mr_fifo_t *fifo);
|
||||
size_t mr_fifo_get_free(const mr_fifo_t *fifo);
|
||||
size_t mr_fifo_get_size(const mr_fifo_t *fifo);
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -97,19 +88,20 @@ size_t mr_fifo_write_force(mr_fifo_t *fifo, const void *buf, size_t count);
|
||||
* @{
|
||||
*/
|
||||
|
||||
mr_class_t *mr_class_find(mr_class_t *parent, const char *path);
|
||||
void mr_class_init(mr_class_t *class, const char *name, size_t priv_size,
|
||||
void mr_class_init(mr_class_t *class, const char *name, size_t privsize,
|
||||
void (*release)(mr_class_t *), void *methods);
|
||||
mr_class_t *mr_class_create(const char *name, uint32_t priv_size, void *methods);
|
||||
mr_class_t *mr_class_create(const char *name, uint32_t privsize, void *methods);
|
||||
int mr_class_add(mr_class_t *class, mr_class_t *parent);
|
||||
void mr_class_delete(mr_class_t *class);
|
||||
int mr_class_rename(mr_class_t *class, const char *name);
|
||||
int mr_class_register(mr_class_t *class, mr_class_t *parent, const char *dir);
|
||||
void mr_class_unregister(mr_class_t *class);
|
||||
mr_class_t *mr_class_get(mr_class_t *class);
|
||||
void mr_class_put(mr_class_t *class);
|
||||
int mr_class_rename(mr_class_t *class, const char *name);
|
||||
void *mr_class_priv_data_get(mr_class_t *class);
|
||||
void *mr_class_methods_get(mr_class_t *class);
|
||||
mr_class_t *mr_class_find(mr_class_t *parent, const char *path);
|
||||
bool mr_class_is_subclass(mr_class_t *class, mr_class_t *base);
|
||||
void *mr_class_get_privdata(mr_class_t *class);
|
||||
void *mr_class_get_methods(mr_class_t *class);
|
||||
char *mr_extract_name(const char *path);
|
||||
char *mr_extract_dir(const char *path);
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ MR_INLINE void mr_list_concat(mr_list_t *list1, mr_list_t *list2)
|
||||
*
|
||||
* @return The length of the list.
|
||||
*/
|
||||
MR_INLINE size_t mr_list_length_get(mr_list_t *list)
|
||||
MR_INLINE size_t mr_list_get_length(mr_list_t *list)
|
||||
{
|
||||
mr_list_t *node;
|
||||
size_t len;
|
||||
|
||||
@@ -84,7 +84,7 @@ MR_INLINE bool mr_ref_put(mr_ref_t *ref, void (*release)(mr_ref_t *))
|
||||
*
|
||||
* @return The reference count.
|
||||
*/
|
||||
MR_INLINE mr_atomic_t mr_ref_count_get(mr_ref_t *ref)
|
||||
MR_INLINE mr_atomic_t mr_ref_get_count(mr_ref_t *ref)
|
||||
{
|
||||
/* Get reference count */
|
||||
return ref->count;
|
||||
|
||||
@@ -73,6 +73,30 @@ extern "C" {
|
||||
*/
|
||||
#define MR_BIT_CLR(_value, _mask) ((_value) &= ~(_mask))
|
||||
|
||||
/**
|
||||
* @brief This macro function gets the maximum of two values.
|
||||
*
|
||||
* @param _type The type of the value.
|
||||
* @param _a The first value.
|
||||
* @param _b The second value.
|
||||
*
|
||||
* @return The maximum of the two values.
|
||||
*/
|
||||
#define MR_MAX(_type, _a, _b) \
|
||||
((_type){(_a)} > (_type){(_b)} ? (_type){(_a)} : (_type){(_b)})
|
||||
|
||||
/**
|
||||
* @brief This macro function gets the minimum of two values.
|
||||
*
|
||||
* @param _type The type of the value.
|
||||
* @param _a The first value.
|
||||
* @param _b The second value.
|
||||
*
|
||||
* @return The minimum of the two values.
|
||||
*/
|
||||
#define MR_MIN(_type, _a, _b) \
|
||||
((_type){(_a)} < (_type){(_b)} ? (_type){(_a)} : (_type){(_b)})
|
||||
|
||||
/**
|
||||
* @brief This macro function ensures that a value is within a specified range.
|
||||
*
|
||||
@@ -82,13 +106,23 @@ extern "C" {
|
||||
*
|
||||
* @return The value within the specified range.
|
||||
*/
|
||||
#define MR_CLAMP(_value, _min, _max) \
|
||||
({ \
|
||||
typeof(_value) __value = (_value); \
|
||||
typeof(_min) __min = (_min); \
|
||||
typeof(_max) __max = (_max); \
|
||||
__value < __min ? __min : (__value > __max ? __max : __value); \
|
||||
})
|
||||
#define MR_CLAMP(_type, _value, _min, _max) \
|
||||
(MR_MAX(_type, MR_MIN(_type, _value, _max), _min))
|
||||
|
||||
/**
|
||||
* @brief This macro function swaps two values.
|
||||
*
|
||||
* @param _type The type of the value.
|
||||
* @param _a The first value.
|
||||
* @param _b The second value.
|
||||
*/
|
||||
#define MR_SWAP(_type, _a, _b) \
|
||||
do \
|
||||
{ \
|
||||
_type __a = (_a); \
|
||||
(_a) = (_b); \
|
||||
(_b) = __a; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief This macro function concatenates two strings.
|
||||
@@ -100,6 +134,15 @@ extern "C" {
|
||||
*/
|
||||
#define MR_CONCAT(_a, _b) _a##_b
|
||||
|
||||
/**
|
||||
* @brief This macro function converts an integer to a string.
|
||||
*
|
||||
* @param _a The integer to convert.
|
||||
*
|
||||
* @return The string representation of the integer.
|
||||
*/
|
||||
#define MR_STR(_a) #_a
|
||||
|
||||
/**
|
||||
* @brief This macro function gets its structure from its member.
|
||||
*
|
||||
@@ -122,89 +165,7 @@ extern "C" {
|
||||
*
|
||||
* @note The variable is local, please use it carefully.
|
||||
*/
|
||||
#define MR_MAKE_LOCAL(_type, ...) (&((_type){__VA_ARGS__}))
|
||||
|
||||
/**
|
||||
* @brief This macro function gets the maximum of two values.
|
||||
*
|
||||
* @param _a The first value.
|
||||
* @param _b The second value.
|
||||
*
|
||||
* @return The maximum of the two values.
|
||||
*/
|
||||
#define MR_MAX(_a, _b) \
|
||||
({ \
|
||||
typeof(_a) __a = (_a); \
|
||||
typeof(_b) __b = (_b); \
|
||||
__a > __b ? __a : __b; \
|
||||
})
|
||||
|
||||
/**
|
||||
* @brief This macro function gets the minimum of two values.
|
||||
*
|
||||
* @param _a The first value.
|
||||
* @param _b The second value.
|
||||
*
|
||||
* @return The minimum of the two values.
|
||||
*/
|
||||
#define MR_MIN(_a, _b) \
|
||||
({ \
|
||||
typeof(_a) __a = (_a); \
|
||||
typeof(_b) __b = (_b); \
|
||||
__a < __b ? __a : __b; \
|
||||
})
|
||||
|
||||
/**
|
||||
* @brief This macro function converts an integer to a string.
|
||||
*
|
||||
* @param _a The integer to convert.
|
||||
*
|
||||
* @return The string representation of the integer.
|
||||
*/
|
||||
#define MR_STR(_a) #_a
|
||||
|
||||
/**
|
||||
* @brief This macro function swaps two values.
|
||||
*
|
||||
* @param _a The first value.
|
||||
* @param _b The second value.
|
||||
*/
|
||||
#define MR_SWAP(_a, _b) \
|
||||
({ \
|
||||
typeof(_a) __a = (_a); \
|
||||
(_a) = (_b); \
|
||||
(_b) = __a; \
|
||||
})
|
||||
|
||||
/**
|
||||
* @brief This macro function converts a value to a boolean.
|
||||
*
|
||||
* @param _value The value to convert.
|
||||
*
|
||||
* @return The boolean value.
|
||||
*/
|
||||
#define MR_TO_BOOL(_value) (!!(_value))
|
||||
|
||||
/**
|
||||
* @brief This macro function provides a with-like construct for execution blocks.
|
||||
*
|
||||
* @param _begin The beginning of the block.
|
||||
* @param _end The end of the block.
|
||||
*
|
||||
* @note Using the 'break' or 'return' may caused 'end' not to executed.
|
||||
*/
|
||||
#define MR_WITH(_begin, _end) \
|
||||
for (bool __with = ({ (_begin), false; }); __with != true; __with = true, (_end))
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @addtogroup Interrupt
|
||||
* @{
|
||||
*/
|
||||
|
||||
size_t mr_interrupt_disable(void);
|
||||
void mr_interrupt_enable(size_t mask);
|
||||
#define MR_LOCAL_MAKE(_type, ...) (&((_type){__VA_ARGS__}))
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -215,50 +176,64 @@ void mr_interrupt_enable(size_t mask);
|
||||
|
||||
#define MR_LOG_TAG ("null")
|
||||
#define __MR_LOG_PRINTF(_tag, _fmt, ...) \
|
||||
({ \
|
||||
do \
|
||||
{ \
|
||||
if (strcmp(_tag, "null") != 0) \
|
||||
{ \
|
||||
printf(_fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
})
|
||||
} while (0)
|
||||
#ifdef MR_USE_LOG_ERROR
|
||||
#define MR_LOG_E(_fmt, ...) \
|
||||
__MR_LOG_PRINTF(MR_LOG_TAG, "[E/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__) /**< Error log */
|
||||
__MR_LOG_PRINTF(MR_LOG_TAG, "[E/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__) /**< Error log */
|
||||
#else
|
||||
#define MR_LOG_E(_fmt, ...)
|
||||
#endif /* MR_USE_LOG_ERROR */
|
||||
#ifdef MR_USE_LOG_WARN
|
||||
#define MR_LOG_W(_fmt, ...) \
|
||||
__MR_LOG_PRINTF(MR_LOG_TAG, "[W/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__) /**< Warning log */
|
||||
__MR_LOG_PRINTF(MR_LOG_TAG, "[W/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__) /**< Warning log */
|
||||
#else
|
||||
#define MR_LOG_W(_fmt, ...)
|
||||
#endif /* MR_USE_LOG_WARN */
|
||||
#ifdef MR_USE_LOG_INFO
|
||||
#define MR_LOG_I(_fmt, ...) \
|
||||
__MR_LOG_PRINTF(MR_LOG_TAG, "[I/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__) /**< Information log */
|
||||
__MR_LOG_PRINTF(MR_LOG_TAG, "[I/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__) /**< Information log */
|
||||
#else
|
||||
#define MR_LOG_I(_fmt, ...)
|
||||
#endif /* MR_USE_LOG_INFO */
|
||||
#ifdef MR_USE_LOG_DEBUG
|
||||
#define MR_LOG_D(_fmt, ...) __MR_LOG_PRINTF(MR_LOG_TAG, "[D/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__)
|
||||
#define MR_LOG_D(_fmt, ...) \
|
||||
__MR_LOG_PRINTF(MR_LOG_TAG, "[D/%s] "_fmt, MR_LOG_TAG, ##__VA_ARGS__) /**< Debug log */
|
||||
#else
|
||||
#define MR_LOG_D(_fmt, ...)
|
||||
#endif /* MR_USE_LOG_DEBUG */
|
||||
#ifdef MR_USE_LOG_ASSERT
|
||||
#define MR_ASSERT(_cond) \
|
||||
({ \
|
||||
do \
|
||||
{ \
|
||||
if (!(_cond)) \
|
||||
{ \
|
||||
__MR_LOG_PRINTF("Assert", "[A/%s] Assertion failed: %s, %s, %d.\r\n", __FUNCTION__, \
|
||||
#_cond, __FILE__, __LINE__); \
|
||||
while (1); \
|
||||
} \
|
||||
})
|
||||
} while (0)
|
||||
#else
|
||||
#define MR_ASSERT(_cond)
|
||||
#endif /* MR_USE_LOG_ASSERT */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @addtogroup Interrupt
|
||||
* @{
|
||||
*/
|
||||
|
||||
size_t mr_irq_disable(void);
|
||||
void mr_irq_enable(size_t mask);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -24,7 +24,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief This macro function initializes the spinlock.
|
||||
*/
|
||||
#define MR_SPINLOCK_INIT() \
|
||||
#define MR_SPIN_LOCK_INIT() \
|
||||
{ \
|
||||
.lock = 0 \
|
||||
}
|
||||
@@ -86,7 +86,7 @@ MR_INLINE size_t mr_spin_lock_irqsave(mr_spinlock_t *lock)
|
||||
size_t mask;
|
||||
|
||||
/* Disable interrupt */
|
||||
mask = mr_interrupt_disable();
|
||||
mask = mr_irq_disable();
|
||||
|
||||
/* Lock spinlock */
|
||||
mr_spin_lock(lock);
|
||||
@@ -107,7 +107,7 @@ MR_INLINE void mr_spin_unlock_irqrestore(mr_spinlock_t *lock, size_t mask)
|
||||
mr_spin_unlock(lock);
|
||||
|
||||
/* Enable mask */
|
||||
mr_interrupt_enable(mask);
|
||||
mr_irq_enable(mask);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
661
source/class.c
661
source/class.c
@@ -46,6 +46,326 @@ static mr_class_t *__class_find(mr_class_t *parent, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function initialize the class.
|
||||
*
|
||||
* @param class The class to initialize.
|
||||
* @param name The name of the class.
|
||||
* @param privsize The size of the private data.
|
||||
* @param release The release function(released when ref-count is 0).
|
||||
* @param methods The methods of the class.
|
||||
*
|
||||
* @note priv_size must be 0 if methods is NULL.
|
||||
*/
|
||||
void mr_class_init(mr_class_t *class, const char *name, size_t privsize,
|
||||
void (*release)(mr_class_t *), void *methods)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
MR_ASSERT(name != NULL);
|
||||
MR_ASSERT((privsize == 0) || (methods != NULL));
|
||||
|
||||
/* Initialize the class */
|
||||
class->name = name;
|
||||
class->parent = NULL;
|
||||
mr_list_init(&class->list);
|
||||
mr_list_init(&class->clist);
|
||||
mr_spin_lock_init(&class->lock);
|
||||
class->privdata = NULL;
|
||||
class->privsize = privsize;
|
||||
mr_ref_init(&class->refcount);
|
||||
class->release = release;
|
||||
class->methods = methods;
|
||||
}
|
||||
|
||||
static void __class_release(mr_class_t *class)
|
||||
{
|
||||
/* Release the class */
|
||||
mr_free(class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function create the class.
|
||||
*
|
||||
* @param name The name of the class.
|
||||
* @param privsize The size of the private data.
|
||||
* @param methods The methods of the class.
|
||||
*
|
||||
* @return The class, or NULL if failed.
|
||||
*
|
||||
* @note priv_size must be 0 if methods is NULL.
|
||||
*/
|
||||
mr_class_t *mr_class_create(const char *name, uint32_t privsize, void *methods)
|
||||
{
|
||||
mr_class_t *class;
|
||||
|
||||
MR_ASSERT(name != NULL);
|
||||
MR_ASSERT((privsize == 0) || (methods != NULL));
|
||||
|
||||
/* Create the class */
|
||||
class = mr_malloc(sizeof(mr_class_t));
|
||||
if (class == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the class */
|
||||
mr_class_init(class, name, privsize, __class_release, methods);
|
||||
return class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function add the class to the parent class.
|
||||
*
|
||||
* @param class The class to add.
|
||||
* @param parent The parent class.
|
||||
*
|
||||
* @return The error code.
|
||||
*/
|
||||
int mr_class_add(mr_class_t *class, mr_class_t *parent)
|
||||
{
|
||||
size_t mask;
|
||||
int ret;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
MR_ASSERT(parent != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
mr_spin_lock(&parent->lock);
|
||||
|
||||
/* Check if the same name class already exists */
|
||||
if (__class_find(parent, class->name) == NULL)
|
||||
{
|
||||
ret = MR_EEXIST;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* Inherit parent class's implementation if current class has no methods */
|
||||
if (class->methods == NULL)
|
||||
{
|
||||
class->privsize = parent->privsize;
|
||||
class->methods = parent->methods;
|
||||
|
||||
/* Child class's private data must be larger than parent's */
|
||||
} else if (class->privsize < parent->privsize)
|
||||
{
|
||||
ret = MR_EINVAL;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* Add the class to the parent */
|
||||
class->parent = parent;
|
||||
mr_list_append(&parent->clist, &class->list);
|
||||
mr_ref_get(&parent->refcount);
|
||||
ret = MR_EOK;
|
||||
|
||||
_exit:
|
||||
/* Unlock the class */
|
||||
mr_spin_unlock(&parent->lock);
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __ref_release(struct mr_ref *ref)
|
||||
{
|
||||
mr_class_t *class;
|
||||
|
||||
/* Get the class from the reference */
|
||||
class = MR_CONTAINER_OF(ref, mr_class_t, refcount);
|
||||
|
||||
/* Remove the class from the list and release the private data */
|
||||
mr_list_remove(&class->list);
|
||||
mr_list_remove(&class->clist);
|
||||
if (class->privdata != NULL)
|
||||
{
|
||||
mr_free(class->privdata);
|
||||
}
|
||||
|
||||
/* Release the class */
|
||||
if (class->release != NULL)
|
||||
{
|
||||
class->release(class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function delete the class.
|
||||
*
|
||||
* @param class The class to delete.
|
||||
*
|
||||
* @note 1.The class will not be visited.
|
||||
* 2.If the class reference count is 0, it will be released.
|
||||
*/
|
||||
void mr_class_delete(mr_class_t *class)
|
||||
{
|
||||
mr_class_t *parent;
|
||||
size_t mask;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
parent = class->parent;
|
||||
if (parent != NULL)
|
||||
{
|
||||
mr_spin_lock(&parent->lock);
|
||||
}
|
||||
|
||||
/* Remove the class */
|
||||
mr_list_remove(&class->list);
|
||||
|
||||
/* Unlock the class */
|
||||
if (parent != NULL)
|
||||
{
|
||||
/* Put the reference */
|
||||
if (mr_ref_put(&parent->refcount, __ref_release) == false)
|
||||
{
|
||||
mr_spin_unlock(&parent->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the reference */
|
||||
if (mr_ref_put(&class->refcount, __ref_release) == true)
|
||||
{
|
||||
/* Enable interrupt */
|
||||
mr_irq_enable(mask);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unlock the class if not release */
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function rename the class.
|
||||
*
|
||||
* @param class The class to rename.
|
||||
* @param name The new name of the class.
|
||||
*
|
||||
* @return The error code.
|
||||
*/
|
||||
int mr_class_rename(mr_class_t *class, const char *name)
|
||||
{
|
||||
mr_class_t *parent;
|
||||
size_t mask;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
MR_ASSERT(name != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
parent = class->parent;
|
||||
if (parent != NULL)
|
||||
{
|
||||
mr_spin_lock(&parent->lock);
|
||||
|
||||
/* Check if the same name class already exists */
|
||||
if (__class_find(parent, name) != NULL)
|
||||
{
|
||||
/* Unlock the class */
|
||||
mr_spin_unlock(&parent->lock);
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
return MR_EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rename the class */
|
||||
class->name = name;
|
||||
|
||||
/* Unlock the class */
|
||||
if (parent != NULL)
|
||||
{
|
||||
mr_spin_unlock(&parent->lock);
|
||||
}
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
return MR_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function register the class to the directory.
|
||||
*
|
||||
* @param class The class to register.
|
||||
* @param parent The parent class.
|
||||
* @param dir The directory of the class.
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
* @note 1.If parent is NULL, path is resolved as an absolute path.
|
||||
* 2.If dir is NULL, the class will be registered to the parent.
|
||||
*/
|
||||
int mr_class_register(mr_class_t *class, mr_class_t *parent, const char *dir)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Find the directory class */
|
||||
parent = mr_class_find(parent, dir);
|
||||
if (parent == NULL)
|
||||
{
|
||||
return MR_ENOENT;
|
||||
}
|
||||
|
||||
/* Add the class to the directory */
|
||||
return mr_class_add(class, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function unregister the class.
|
||||
*
|
||||
* @param class The class to unregister.
|
||||
*
|
||||
* @note 1.The class will not be visited.
|
||||
* 2.If the class reference count is 0, it will be released.
|
||||
*/
|
||||
void mr_class_unregister(mr_class_t *class)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Delete the class from the root class */
|
||||
mr_class_delete(class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function get the reference of the class.
|
||||
*
|
||||
* @param class The class.
|
||||
*
|
||||
* @return The class.
|
||||
*/
|
||||
mr_class_t *mr_class_get(mr_class_t *class)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Get the reference */
|
||||
mr_ref_get(&class->refcount);
|
||||
return class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function put the reference of the class.
|
||||
*
|
||||
* @param class The class.
|
||||
*/
|
||||
void mr_class_put(mr_class_t *class)
|
||||
{
|
||||
size_t mask;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
|
||||
/* Put the reference */
|
||||
if (mr_ref_put(&class->refcount, __ref_release) == true)
|
||||
{
|
||||
/* Enable interrupt */
|
||||
mr_irq_enable(mask);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unlock the class if not release */
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function find the class.
|
||||
*
|
||||
@@ -54,8 +374,7 @@ static mr_class_t *__class_find(mr_class_t *parent, const char *name)
|
||||
*
|
||||
* @return The class.
|
||||
*
|
||||
* @note 1.If parent is NULL, path is resolved as an absolute path.
|
||||
* 2.If parent is not NULL, path is resolved as a relative path.
|
||||
* @note If parent is NULL, path is resolved as an absolute path.
|
||||
*/
|
||||
mr_class_t *mr_class_find(mr_class_t *parent, const char *path)
|
||||
{
|
||||
@@ -115,346 +434,66 @@ mr_class_t *mr_class_find(mr_class_t *parent, const char *path)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function initialize the class.
|
||||
*
|
||||
* @param class The class to initialize.
|
||||
* @param name The name of the class.
|
||||
* @param priv_size The size of the private data.
|
||||
* @param release The release function(released when ref-count is 0).
|
||||
* @param methods The methods of the class.
|
||||
*
|
||||
* @note priv_size must be 0 if methods is NULL.
|
||||
*/
|
||||
void mr_class_init(mr_class_t *class, const char *name, size_t priv_size,
|
||||
void (*release)(mr_class_t *), void *methods)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
MR_ASSERT(name != NULL);
|
||||
MR_ASSERT((priv_size == 0) || (methods != NULL));
|
||||
|
||||
/* Initialize the class */
|
||||
class->name = name;
|
||||
class->parent = NULL;
|
||||
mr_list_init(&class->list);
|
||||
mr_list_init(&class->clist);
|
||||
mr_spin_lock_init(&class->lock);
|
||||
class->priv_data = NULL;
|
||||
class->priv_size = priv_size;
|
||||
mr_ref_init(&class->ref_count);
|
||||
class->release = release;
|
||||
class->methods = methods;
|
||||
}
|
||||
|
||||
static void __class_release(mr_class_t *class)
|
||||
{
|
||||
/* Release the class */
|
||||
mr_free(class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function create the class.
|
||||
*
|
||||
* @param name The name of the class.
|
||||
* @param priv_size The size of the private data.
|
||||
* @param methods The methods of the class.
|
||||
*
|
||||
* @return The class, or NULL if failed.
|
||||
*
|
||||
* @note priv_size must be 0 if methods is NULL.
|
||||
*/
|
||||
mr_class_t *mr_class_create(const char *name, uint32_t priv_size, void *methods)
|
||||
{
|
||||
mr_class_t *class;
|
||||
|
||||
MR_ASSERT(name != NULL);
|
||||
MR_ASSERT((priv_size == 0) || (methods != NULL));
|
||||
|
||||
/* Create the class */
|
||||
class = mr_malloc(sizeof(mr_class_t));
|
||||
if (class == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the class */
|
||||
mr_class_init(class, name, priv_size, __class_release, methods);
|
||||
return class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function add the class to the parent class.
|
||||
*
|
||||
* @param class The class to add.
|
||||
* @param parent The parent class.
|
||||
*
|
||||
* @return The error code.
|
||||
*/
|
||||
int mr_class_add(mr_class_t *class, mr_class_t *parent)
|
||||
{
|
||||
size_t mask;
|
||||
int ret;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
MR_ASSERT(parent != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
mr_spin_lock(&parent->lock);
|
||||
|
||||
/* Add the class if not exist same name class */
|
||||
if (__class_find(parent, class->name) == NULL)
|
||||
{
|
||||
/* Add the class to the list */
|
||||
class->parent = parent;
|
||||
mr_list_append(&parent->clist, &class->list);
|
||||
|
||||
/* Inherit parent class's implementation if current class has no methods */
|
||||
if (class->methods == NULL)
|
||||
{
|
||||
class->priv_size = parent->priv_size;
|
||||
class->methods = parent->methods;
|
||||
}
|
||||
|
||||
/* Get the reference */
|
||||
mr_ref_get(&parent->ref_count);
|
||||
ret = MR_EOK;
|
||||
} else
|
||||
{
|
||||
ret = MR_EEXIST;
|
||||
}
|
||||
|
||||
/* Unlock the class */
|
||||
mr_spin_unlock(&parent->lock);
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __ref_release(struct mr_ref *ref)
|
||||
{
|
||||
mr_class_t *class;
|
||||
|
||||
/* Get the class from the reference */
|
||||
class = MR_CONTAINER_OF(ref, mr_class_t, ref_count);
|
||||
|
||||
/* Remove the class from the list and release the private data */
|
||||
mr_list_remove(&class->list);
|
||||
mr_list_remove(&class->clist);
|
||||
if (class->priv_data != NULL)
|
||||
{
|
||||
mr_free(class->priv_data);
|
||||
}
|
||||
|
||||
/* Release the class */
|
||||
if (class->release != NULL)
|
||||
{
|
||||
class->release(class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function delete the class.
|
||||
*
|
||||
* @param class The class to delete.
|
||||
*
|
||||
* @note 1.The class will not be visited.
|
||||
* 2.If the class reference count is 0, it will be released.
|
||||
*/
|
||||
void mr_class_delete(mr_class_t *class)
|
||||
{
|
||||
mr_class_t *parent;
|
||||
size_t mask;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
parent = class->parent;
|
||||
if (parent != NULL)
|
||||
{
|
||||
mr_spin_lock(&parent->lock);
|
||||
}
|
||||
|
||||
/* Remove the class */
|
||||
mr_list_remove(&class->list);
|
||||
|
||||
/* Unlock the class */
|
||||
if (parent != NULL)
|
||||
{
|
||||
/* Put the reference */
|
||||
if (mr_ref_put(&parent->ref_count, __ref_release) == false)
|
||||
{
|
||||
mr_spin_unlock(&parent->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the reference */
|
||||
if (mr_ref_put(&class->ref_count, __ref_release) == true)
|
||||
{
|
||||
/* Enable interrupt */
|
||||
mr_interrupt_enable(mask);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unlock the class if not release */
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function register the class to the directory.
|
||||
*
|
||||
* @param class The class to register.
|
||||
* @param parent The parent class.
|
||||
* @param dir The directory of the class.
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
* @note 1.If parent is NULL, path is resolved as an absolute path.
|
||||
* 2.If parent is not NULL, path is resolved as a relative path.
|
||||
* 3.If dir is NULL, the class will be registered to the parent.
|
||||
*/
|
||||
int mr_class_register(mr_class_t *class, mr_class_t *parent, const char *dir)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Find the directory class */
|
||||
parent = mr_class_find(parent, dir);
|
||||
if (parent == NULL)
|
||||
{
|
||||
return MR_ENOENT;
|
||||
}
|
||||
|
||||
/* Add the class to the directory */
|
||||
return mr_class_add(class, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function unregister the class.
|
||||
*
|
||||
* @param class The class to unregister.
|
||||
*
|
||||
* @note 1.The class will not be visited.
|
||||
* 2.If the class reference count is 0, it will be released.
|
||||
*/
|
||||
void mr_class_unregister(mr_class_t *class)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Delete the class from the root class */
|
||||
mr_class_delete(class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function get the reference of the class.
|
||||
* @brief This function check if the class is a subclass of the base class.
|
||||
*
|
||||
* @param class The class.
|
||||
* @param base The base class.
|
||||
*
|
||||
* @return The class.
|
||||
* @return True if the class is a subclass of the base class, False otherwise.
|
||||
*/
|
||||
mr_class_t *mr_class_get(mr_class_t *class)
|
||||
bool mr_class_is_subclass(mr_class_t *class, mr_class_t *base)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
MR_ASSERT(base != NULL);
|
||||
|
||||
/* Get the reference */
|
||||
mr_ref_get(&class->ref_count);
|
||||
return class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function put the reference of the class.
|
||||
*
|
||||
* @param class The class.
|
||||
*/
|
||||
void mr_class_put(mr_class_t *class)
|
||||
{
|
||||
size_t mask;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
|
||||
/* Put the reference */
|
||||
if (mr_ref_put(&class->ref_count, __ref_release) == true)
|
||||
/* Check if the class is a subclass of the base class */
|
||||
while (class != NULL)
|
||||
{
|
||||
/* Enable interrupt */
|
||||
mr_interrupt_enable(mask);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unlock the class if not release */
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function rename the class.
|
||||
*
|
||||
* @param class The class to rename.
|
||||
* @param name The new name of the class.
|
||||
*
|
||||
* @return The error code.
|
||||
*/
|
||||
int mr_class_rename(mr_class_t *class, const char *name)
|
||||
{
|
||||
mr_class_t *parent;
|
||||
size_t mask;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
MR_ASSERT(name != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
parent = class->parent;
|
||||
if (parent != NULL)
|
||||
{
|
||||
mr_spin_lock(&parent->lock);
|
||||
|
||||
/* Check if the same name class already exists */
|
||||
if (__class_find(parent, name) != NULL)
|
||||
if (class == base)
|
||||
{
|
||||
/* Unlock the class */
|
||||
mr_spin_unlock(&parent->lock);
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
return MR_EEXIST;
|
||||
return true;
|
||||
}
|
||||
class = class->parent;
|
||||
}
|
||||
|
||||
/* Rename the class */
|
||||
class->name = name;
|
||||
|
||||
/* Unlock the class */
|
||||
if (parent != NULL)
|
||||
{
|
||||
mr_spin_unlock(&parent->lock);
|
||||
}
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
return MR_EOK;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function get the private data of the class.
|
||||
*
|
||||
* @param class The class.
|
||||
*
|
||||
* @return The private data.
|
||||
*/
|
||||
void *mr_class_priv_data_get(mr_class_t *class)
|
||||
void *mr_class_get_privdata(mr_class_t *class)
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
/* Lock the class */
|
||||
mask = mr_spin_lock_irqsave(&class->lock);
|
||||
|
||||
/* Allocate the private data */
|
||||
if ((class->priv_data == NULL) && (class->priv_size > 0))
|
||||
if ((class->privdata == NULL) && (class->privsize > 0))
|
||||
{
|
||||
class->priv_data = mr_malloc(class->priv_size);
|
||||
class->privdata = mr_malloc(class->privsize);
|
||||
memset(class->privdata, 0, class->privsize);
|
||||
}
|
||||
|
||||
/* Get the private data */
|
||||
return class->priv_data;
|
||||
/* Unlock the class */
|
||||
mr_spin_unlock_irqrestore(&class->lock, mask);
|
||||
return class->privdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function get the methods of the class.
|
||||
*
|
||||
*
|
||||
* @param class The class.
|
||||
*
|
||||
* @return The methods.
|
||||
*/
|
||||
void *mr_class_methods_get(mr_class_t *class)
|
||||
void *mr_class_get_methods(mr_class_t *class)
|
||||
{
|
||||
MR_ASSERT(class != NULL);
|
||||
|
||||
|
||||
134
source/fifo.c
134
source/fifo.c
@@ -31,19 +31,6 @@ int mr_fifo_init(mr_fifo_t *fifo, void *buf, size_t size)
|
||||
return MR_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function resets a fifo.
|
||||
*
|
||||
* @param fifo The fifo.
|
||||
*/
|
||||
void mr_fifo_reset(mr_fifo_t *fifo)
|
||||
{
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
fifo->in = 0;
|
||||
fifo->out = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function allocates a fifo.
|
||||
*
|
||||
@@ -97,60 +84,16 @@ void mr_fifo_free(mr_fifo_t *fifo)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the used space of a fifo.
|
||||
* @brief This function resets a fifo.
|
||||
*
|
||||
* @param fifo The fifo.
|
||||
*
|
||||
* @return The used space.
|
||||
*/
|
||||
size_t mr_fifo_used_get(const mr_fifo_t *fifo)
|
||||
{
|
||||
uint32_t in, out;
|
||||
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
/* Get the in and out */
|
||||
in = fifo->in;
|
||||
out = fifo->out;
|
||||
|
||||
/* Calculate the used space */
|
||||
return (in >= out) ? in - out : fifo->size - (out - in);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the free space of a fifo.
|
||||
*
|
||||
* @param fifo The fifo.
|
||||
*
|
||||
* @return The free space.
|
||||
*/
|
||||
size_t mr_fifo_space_get(const mr_fifo_t *fifo)
|
||||
{
|
||||
uint32_t in, out;
|
||||
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
/* Get the in and out */
|
||||
in = fifo->in;
|
||||
out = fifo->out;
|
||||
|
||||
/* Calculate the free space */
|
||||
return (in >= out) ? fifo->size - (in - out) - 1 : out - in - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the size of a fifo.
|
||||
*
|
||||
* @param fifo The fifo.
|
||||
*
|
||||
* @return The size.
|
||||
*/
|
||||
size_t mr_fifo_size_get(const mr_fifo_t *fifo)
|
||||
void mr_fifo_reset(mr_fifo_t *fifo)
|
||||
{
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
/* Return the buffer size that can be used */
|
||||
return (fifo->size == 0) ? 0 : fifo->size - 1;
|
||||
fifo->in = 0;
|
||||
fifo->out = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +113,7 @@ size_t mr_fifo_peek(const mr_fifo_t *fifo, void *buf, size_t count)
|
||||
MR_ASSERT((buf != NULL) || (count == 0));
|
||||
|
||||
/* Get used space, limit by count */
|
||||
used = mr_fifo_used_get(fifo);
|
||||
used = mr_fifo_get_used(fifo);
|
||||
if (used < count)
|
||||
{
|
||||
count = used;
|
||||
@@ -211,7 +154,7 @@ size_t mr_fifo_discard(mr_fifo_t *fifo, size_t count)
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
/* Get used space, limit by count */
|
||||
used = mr_fifo_used_get(fifo);
|
||||
used = mr_fifo_get_used(fifo);
|
||||
if (used < count)
|
||||
{
|
||||
count = used;
|
||||
@@ -256,7 +199,7 @@ size_t mr_fifo_read(mr_fifo_t *fifo, void *buf, size_t count)
|
||||
MR_ASSERT((buf != NULL) || (count == 0));
|
||||
|
||||
/* Get used space, limit by count */
|
||||
used = mr_fifo_used_get(fifo);
|
||||
used = mr_fifo_get_used(fifo);
|
||||
if (used < count)
|
||||
{
|
||||
count = used;
|
||||
@@ -304,7 +247,7 @@ size_t mr_fifo_write(mr_fifo_t *fifo, const void *buf, size_t count)
|
||||
MR_ASSERT((buf != NULL) || (count == 0));
|
||||
|
||||
/* Get free space, limit by count */
|
||||
free = mr_fifo_space_get(fifo);
|
||||
free = mr_fifo_get_free(fifo);
|
||||
if (free < count)
|
||||
{
|
||||
count = free;
|
||||
@@ -355,7 +298,7 @@ size_t mr_fifo_write_force(mr_fifo_t *fifo, const void *buf, size_t count)
|
||||
MR_ASSERT((buf != NULL) || (count == 0));
|
||||
|
||||
/* Skip data that exceeds the size */
|
||||
size = mr_fifo_size_get(fifo);
|
||||
size = mr_fifo_get_size(fifo);
|
||||
if (count > size)
|
||||
{
|
||||
buf = &((const uint8_t *)buf)[count - size];
|
||||
@@ -363,7 +306,7 @@ size_t mr_fifo_write_force(mr_fifo_t *fifo, const void *buf, size_t count)
|
||||
}
|
||||
|
||||
/* Discard data that will be overwritten */
|
||||
free = mr_fifo_space_get(fifo);
|
||||
free = mr_fifo_get_free(fifo);
|
||||
if (free < count)
|
||||
{
|
||||
mr_fifo_discard(fifo, count - free);
|
||||
@@ -372,3 +315,60 @@ size_t mr_fifo_write_force(mr_fifo_t *fifo, const void *buf, size_t count)
|
||||
/* Write data */
|
||||
return mr_fifo_write(fifo, buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the used space of a fifo.
|
||||
*
|
||||
* @param fifo The fifo.
|
||||
*
|
||||
* @return The used space.
|
||||
*/
|
||||
size_t mr_fifo_get_used(const mr_fifo_t *fifo)
|
||||
{
|
||||
uint32_t in, out;
|
||||
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
/* Get the in and out */
|
||||
in = fifo->in;
|
||||
out = fifo->out;
|
||||
|
||||
/* Calculate the used space */
|
||||
return (in >= out) ? in - out : fifo->size - (out - in);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the free space of a fifo.
|
||||
*
|
||||
* @param fifo The fifo.
|
||||
*
|
||||
* @return The free space.
|
||||
*/
|
||||
size_t mr_fifo_get_free(const mr_fifo_t *fifo)
|
||||
{
|
||||
uint32_t in, out;
|
||||
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
/* Get the in and out */
|
||||
in = fifo->in;
|
||||
out = fifo->out;
|
||||
|
||||
/* Calculate the free space */
|
||||
return (in >= out) ? fifo->size - (in - out) - 1 : out - in - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the size of a fifo.
|
||||
*
|
||||
* @param fifo The fifo.
|
||||
*
|
||||
* @return The size.
|
||||
*/
|
||||
size_t mr_fifo_get_size(const mr_fifo_t *fifo)
|
||||
{
|
||||
MR_ASSERT(fifo != NULL);
|
||||
|
||||
/* Return the buffer size that can be used */
|
||||
return (fifo->size == 0) ? 0 : fifo->size - 1;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ MR_WEAK void *mr_malloc(size_t size)
|
||||
size_t mask;
|
||||
|
||||
/* Disable interrupt */
|
||||
mask = mr_interrupt_disable();
|
||||
mask = mr_irq_disable();
|
||||
|
||||
/* Check size and residual memory */
|
||||
prev = &__heap_start;
|
||||
@@ -143,7 +143,7 @@ MR_WEAK void *mr_malloc(size_t size)
|
||||
|
||||
_exit:
|
||||
/* Enable interrupt */
|
||||
mr_interrupt_enable(mask);
|
||||
mr_irq_enable(mask);
|
||||
return memory;
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ MR_WEAK void mr_free(void *memory)
|
||||
}
|
||||
|
||||
/* Disable interrupt */
|
||||
mask = mr_interrupt_disable();
|
||||
mask = mr_irq_disable();
|
||||
|
||||
/* Check the block */
|
||||
block = (mr_heap_block_t *)((uint8_t *)memory - sizeof(mr_heap_block_t));
|
||||
@@ -176,7 +176,7 @@ MR_WEAK void mr_free(void *memory)
|
||||
}
|
||||
|
||||
/* Enable interrupt */
|
||||
mr_interrupt_enable(mask);
|
||||
mr_irq_enable(mask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,19 +41,19 @@ void mr_auto_init(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function disable the interrupt.
|
||||
* @brief This function disable interrupt.
|
||||
*/
|
||||
MR_WEAK size_t mr_interrupt_disable(void)
|
||||
MR_WEAK size_t mr_irq_disable(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function enable the interrupt.
|
||||
* @brief This function enable interrupt.
|
||||
*
|
||||
* @param mask The interrupt mask.
|
||||
*/
|
||||
MR_WEAK void mr_interrupt_enable(MR_UNUSED size_t mask)
|
||||
MR_WEAK void mr_irq_enable(MR_UNUSED size_t mask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user