对象管理器初始化
一、对象结构体体
//base structure of kernel object
struct rt_object
{
#if RT_NAME_MAX > 0
char name[RT_NAME_MAX]; /**< dynamic name of kernel object */
#else
const char *name; /**< static name of kernel object */
#endif /* RT_NAME_MAX > 0 */
rt_uint8_t type; /**< type of kernel object */
rt_uint8_t flag; //flag of kernel object
#ifdef RT_USING_MODULE
void * module_id; /**< id of application module */
#endif /* RT_USING_MODULE */
#ifdef RT_USING_SMART
int lwp_ref_count; /**< ref count for lwp */
#endif /* RT_USING_SMART */
rt_list_t list; /**< list node of kernel object */
};
typedef struct rt_object *rt_object_t; /**< Type for kernel objects. */
二、对象管理器操作函数
1、rt_object_get_information 函数,根据对象类型,获取对象信息结构体。
/**
* @brief This function will return the specified type of object information.
*
* @param type is the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
*
* @return the object type information or RT_NULL
*/
struct rt_object_information *
rt_object_get_information(enum rt_object_class_type type)
{
int index;
for (index = 0; index < RT_Object_Info_Unknown; index ++)
if (_object_container[index].type == type) return &_object_container[index];
return RT_NULL;
}
RTM_EXPORT(rt_object_get_information);
2、rt_object_get_length函数,根据对象类型,获取对象信息结构体的对象链表大小。
/**
* @brief This function will return the length of object list in object container.
*
* @param type is the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
*
* @return the length of object list
*/
int rt_object_get_length(enum rt_object_class_type type)
{
int count = 0;
rt_base_t level;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;
information = rt_object_get_information((enum rt_object_class_type)type);
if (information == RT_NULL) return 0;
level = rt_hw_interrupt_disable();
/* get the count of objects */
rt_list_for_each(node, &(information->object_list))
{
count ++;
}
rt_hw_interrupt_enable(level);
return count;
}
RTM_EXPORT(rt_object_get_length);
遍历链表
/**
* rt_list_for_each - iterate over a list
* @param pos the rt_list_t * to use as a loop cursor.
* @param head the head for your list.
*/
#define rt_list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
3、rt_object_get_pointers函数,此函数将复制指定类型的对象指针,最大大小由maxlen决定。
/**
* @brief This function will copy the object pointer of the specified type,
* with the maximum size specified by maxlen.
*
* @param type is the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
*
* @param pointers is the pointer will be saved to.
*
* @param maxlen is the maximum number of pointers can be saved.
*
* @return the copied number of object pointers.
*/
int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen)
{
int index = 0;
rt_base_t level;
struct rt_object *object;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;
if (maxlen <= 0) return 0;
information = rt_object_get_information((enum rt_object_class_type)type);
if (information == RT_NULL) return 0;
level = rt_hw_interrupt_disable();
/* retrieve pointer of object */
rt_list_for_each(node, &(information->object_list))
{
object = rt_list_entry(node, struct rt_object, list);
pointers[index] = object;
index ++;
if (index >= maxlen) break;
}
rt_hw_interrupt_enable(level);
return index;
}
RTM_EXPORT(rt_object_get_pointers);
/**
* @brief get the struct for this entry
* @param node the entry point
* @param type the type of structure
* @param member the name of list in structure
*/
#define rt_list_entry(node, type, member) \
rt_container_of(node, type, member)
获取结构体类型的首地址,ptr指针是结构体类型的一个成员变量的指针,由member算出这个成员变量的偏移地址,从而计算出ptr所在结构体的首地址。
/**
* rt_container_of - return the start address of struct type, while ptr is the
* member of struct type.
*/
#define rt_container_of(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
4、rt_object_init函数,此函数将初始化一个对象,并加入对象管理器中管理。
/**
* @brief This function will initialize an object and add it to object system
* management.
*
* @param object is the specified object to be initialized.
*
* @param type is the object type.
*
* @param name is the object name. In system, the object's name must be unique.
*/
void rt_object_init(struct rt_object *object,
enum rt_object_class_type type,
const char *name)
{
rt_base_t level;
#ifdef RT_USING_DEBUG
struct rt_list_node *node = RT_NULL;
#endif
struct rt_object_information *information;
#ifdef RT_USING_MODULE
struct rt_dlmodule *module = dlmodule_self();
#endif /* RT_USING_MODULE */
/* get object information */
information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL);
#ifdef RT_USING_DEBUG
/* check object type to avoid re-initialization */
/* enter critical */
rt_enter_critical();
/* try to find object */
for (node = information->object_list.next;
node != &(information->object_list);
node = node->next)
{
struct rt_object *obj;
obj = rt_list_entry(node, struct rt_object, list);
RT_ASSERT(obj != object);
}
/* leave critical */
rt_exit_critical();
#endif
/* initialize object's parameters */
/* set object type to static */
object->type = type | RT_Object_Class_Static;
#if RT_NAME_MAX > 0
rt_strncpy(object->name, name, RT_NAME_MAX); /* copy name */
#else
object->name = name;
#endif /* RT_NAME_MAX > 0 */
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
/* lock interrupt */
level = rt_hw_interrupt_disable();
#ifdef RT_USING_MODULE
if (module)
{
rt_list_insert_after(&(module->object_list), &(object->list));
object->module_id = (void *)module;
}
else
#endif /* RT_USING_MODULE */
{
/* insert object into information object list */
rt_list_insert_after(&(information->object_list), &(object->list));
}
/* unlock interrupt */
rt_hw_interrupt_enable(level);
}
链表向后插入一个结点
/**
* @brief insert a node after a list
*
* @param l list to insert it
* @param n new node to be inserted
*/
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
{
l->next->prev = n;
n->next = l->next;
l->next = n;
n->prev = l;
}
5、rt_object_detach 函数,将静态对象从对象管理器链表中移除,但并未释放其内存。
/**
* @brief This function will detach a static object from object system,
* and the memory of static object is not freed.
*
* @param object the specified object to be detached.
*/
void rt_object_detach(rt_object_t object)
{
rt_base_t level;
/* object check */
RT_ASSERT(object != RT_NULL);
RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
/* reset object type */
object->type = 0;
/* lock interrupt */
level = rt_hw_interrupt_disable();
/* remove from old list */
rt_list_remove(&(object->list));
/* unlock interrupt */
rt_hw_interrupt_enable(level);
}
从链表中移除
/**
* @brief remove node from list.
* @param n the node to remove from the list.
*/
rt_inline void rt_list_remove(rt_list_t *n)
{
n->next->prev = n->prev;
n->prev->next = n->next;
n->next = n->prev = n;
}
6、rt_object_allocate函数,动态创建一个对象,并加入对象管理器中管理。
/**
* @brief This function will allocate an object from object system.
*
* @param type is the type of object.
*
* @param name is the object name. In system, the object's name must be unique.
*
* @return object
*/
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{
struct rt_object *object;
rt_base_t level;
struct rt_object_information *information;
#ifdef RT_USING_MODULE
struct rt_dlmodule *module = dlmodule_self();
#endif /* RT_USING_MODULE */
RT_DEBUG_NOT_IN_INTERRUPT;
//get object information
information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL);
object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
if (object == RT_NULL)
{
//no memory can be allocated
return RT_NULL;
}
//clean memory data of object
rt_memset(object, 0x0, information->object_size);
//initialize object's parameters
//set object type
object->type = type;
//set object type
object->flag = 0;
#if RT_NAME_MAX > 0
rt_strncpy(object->name, name, RT_NAME_MAX); /* copy name */
#else
object->name = name;
#endif /* RT_NAME_MAX > 0 */
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
//lock interrupt
level = rt_hw_interrupt_disable();
#ifdef RT_USING_MODULE
if (module)
{
rt_list_insert_after(&(module->object_list), &(object->list));
object->module_id = (void *)module;
}
else
#endif /* RT_USING_MODULE */
{
//insert object into information object list
rt_list_insert_after(&(information->object_list), &(object->list));
}
//unlock interrupt
rt_hw_interrupt_enable(level);
//return object
return object;
}
7、rt_object_delete函数,删除一个对象,并释放其内存。
/**
* @brief This function will delete an object and release object memory.
*
* @param object is the specified object to be deleted.
*/
void rt_object_delete(rt_object_t object)
{
rt_base_t level;
/* object check */
RT_ASSERT(object != RT_NULL);
RT_ASSERT(!(object->type & RT_Object_Class_Static));
RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
/* reset object type */
object->type = RT_Object_Class_Null;
/* lock interrupt */
level = rt_hw_interrupt_disable();
/* remove from old list */
rt_list_remove(&(object->list));
/* unlock interrupt */
rt_hw_interrupt_enable(level);
/* free the memory of object */
RT_KERNEL_FREE(object);
}
8、rt_object_is_systemobject ,判断是否是系统对象。
/**
* @brief This function will judge the object is system object or not.
*
* @note Normally, the system object is a static object and the type
* of object set to RT_Object_Class_Static.
*
* @param object is the specified object to be judged.
*
* @return RT_TRUE if a system object, RT_FALSE for others.
*/
rt_bool_t rt_object_is_systemobject(rt_object_t object)
{
/* object check */
RT_ASSERT(object != RT_NULL);
if (object->type & RT_Object_Class_Static)
return RT_TRUE;
return RT_FALSE;
}
9、获取对象类型。
/**
* @brief This function will return the type of object without
* RT_Object_Class_Static flag.
*
* @param object is the specified object to be get type.
*
* @return the type of object.
*/
rt_uint8_t rt_object_get_type(rt_object_t object)
{
/* object check */
RT_ASSERT(object != RT_NULL);
return object->type & ~RT_Object_Class_Static;
}
10、rt_object_find函数,根据名字和类型在对象管理器中查找一个对象。
/**
* @brief This function will find specified name object from object
* container.
*
* @param name is the specified name of object.
*
* @param type is the type of object
*
* @return the found object or RT_NULL if there is no this object
* in object container.
*
* @note this function shall not be invoked in interrupt status.
*/
rt_object_t rt_object_find(const char *name, rt_uint8_t type)
{
struct rt_object *object = RT_NULL;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;
information = rt_object_get_information((enum rt_object_class_type)type);
/* parameter check */
if ((name == RT_NULL) || (information == RT_NULL)) return RT_NULL;
/* which is invoke in interrupt status */
RT_DEBUG_NOT_IN_INTERRUPT;
/* enter critical */
rt_enter_critical();
/* try to find object */
rt_list_for_each(node, &(information->object_list))
{
object = rt_list_entry(node, struct rt_object, list);
if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
{
/* leave critical */
rt_exit_critical();
return object;
}
}
/* leave critical */
rt_exit_critical();
return RT_NULL;
}
11、rt_object_get_name函数,获取对象的名字。
/**
* @brief This function will return the name of the specified object container
*
* @param object the specified object to be get name
* @param name buffer to store the object name string
* @param name_size maximum size of the buffer to store object name
*
* @return -RT_EINVAL if any parameter is invalid or RT_EOK if the operation is successfully executed
*
* @note this function shall not be invoked in interrupt status
*/
rt_err_t rt_object_get_name(rt_object_t object, char *name, rt_uint8_t name_size)
{
rt_err_t result = -RT_EINVAL;
if ((object != RT_NULL) && (name != RT_NULL) && (name_size != 0U))
{
const char *obj_name = object->name;
(void) rt_strncpy(name, obj_name, (rt_size_t)name_size);
result = RT_EOK;
}
return result;
}