源码文件:RT-Thread Nano V3.1.3\src\object.c (源文件修改日期:2018-01-25)
RT-Thread官网:https://www.rt-thread.org/
RT-Thread内核采用面向对象的设计思想进行设计,系统级的基础设施都是一种内核对象,例如线程,信号量,互斥量,定时器等。
对象容器中包含了每类内核对象的信息,包括对象类型,大小等。
对象容器给每类内核对象分配了一个链表,所有的内核对象都被链接到该链表上。
如图 RT-Thread 的内核对象容器及链表如下图所示:
从面向对象的观点,可以认为每一种具体对象是抽象对象的派生,继承了基本对象的属性并在此基础上扩展了与自己相关的属性。
在对象管理模块中,定义了通用的数据结构struct rt_object
,用来保存各种对象的共同属性,各种具体对象只需要在此基础上加上自己的某些特别的属性,就可以清楚的表示自己的特征。
这种设计方法的优点有:
线程对象、内存池对象、定时器对象、设备对象和 IPC对象
(Inter-Process Communication);由 IPC对象
派生出信号量、互斥量、事件集、邮箱、消息队列、信号等。
简单的说,在RT-Thread中,所有具体对象数据结构的根就是rt_object
;
/**
* Base structure of Kernel object
*/
struct rt_object
{
char name[RT_NAME_MAX]; /**< name of kernel object */
rt_uint8_t type; /**< type of kernel object */
rt_uint8_t flag; /**< flag of kernel object */
#ifdef RT_USING_MODULE /* 请忽略module成员 */
void *module_id; /**< id of application module */
#endif
rt_list_t list; /**< list node of kernel object */
};
typedef struct rt_object *rt_object_t; /**< Type for kernel objects. */
内核对象支持的类型(type)有:
enum rt_object_class_type
{
RT_Object_Class_Null = 0, /**< The object is not used. */
RT_Object_Class_Thread, /**< The object is a thread. */
RT_Object_Class_Semaphore, /**< The object is a semaphore. */
RT_Object_Class_Mutex, /**< The object is a mutex. */
RT_Object_Class_Event, /**< The object is a event. */
RT_Object_Class_MailBox, /**< The object is a mail box. */
RT_Object_Class_MessageQueue, /**< The object is a message queue. */
RT_Object_Class_MemHeap, /**< The object is a memory heap */
RT_Object_Class_MemPool, /**< The object is a memory pool. */
RT_Object_Class_Device, /**< The object is a device */
RT_Object_Class_Timer, /**< The object is a timer. */
RT_Object_Class_Module, /**< The object is a module. */
RT_Object_Class_Unknown, /**< The object is unknown. */
RT_Object_Class_Static = 0x80 /**< The object is a static object. */
};
注:如 果 是 静 态 对 象, 那 么 对 象 类 型 的 最 高 位 将 是 1(是RT_Object_Class_Static与其他对象类型的与操作);
/**
* The information of the kernel object
*/
struct rt_object_information
{
enum rt_object_class_type type; /**< object class type */
rt_list_t object_list; /**< object list */
rt_size_t object_size; /**< object size */
};
RT-Thread代码在开发编译时,会初始化一个rt_object_information
类型的数组,作为内核对象容器。
一类对象由一个容器数组成员管理,该数组成员作为一类对象的链表头管理其他链表节点。
对象容器数组初始化时,数组成员的链表头均指向自己。
当用户初始化/创建的具体对象实例时,对象实例通过链表节点的形式挂接在object_list
上。
函数功能:根据指定类型,从对象容器数组中获取数组成员的入口地址
函数内容:无
函数应用:核心代码
/**
* This function will return the specified type of object information.
*
* @param type the type of object
* @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 (rt_object_container[index].type == type) return &rt_object_container[index];
return RT_NULL;
}
函数功能:初始化对象,该函数将初始化一个静态对象并将其放到系统对象管理器中。
函数内容:
函数应用:核心代码
/**
* This function will initialize an object and add it to object system
* management.
*
* @param object the specified object to be initialized.
* 被初始化的指定对象;它必须指向具体的对象内存块,而不能是空指针或野指针
* @param type the object type.
* 初始化对象的类型;
* @param name 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)
{
register rt_base_t temp;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information;
#ifdef RT_USING_MODULE
struct rt_dlmodule *module = dlmodule_self();
#endif
/* get object information */ /* 第一步 */
information = rt_object_get_information(type); /* 从对象容器中,获取指定一类对象的数组成员入口地址 */
RT_ASSERT(information != RT_NULL);
/* 第二步 */
/* 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();
/* initialize object's parameters */ /* 第三步:初始化对象参数 */
/* set object type to static */
object->type = type | RT_Object_Class_Static; /* 设置为静态对象类型 */
/* copy name */
rt_strncpy(object->name, name, RT_NAME_MAX); /* 设置对象实例的name成员 */
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object)); /* 默认不用RT_USING_HOOK时,为空 */
/* lock interrupt */
temp = rt_hw_interrupt_disable(); /* 关闭硬件中断 */
#ifdef RT_USING_MODULE /* 默认不用RT_USING_MODULE */
if (module)
{
rt_list_insert_after(&(module->object_list), &(object->list)); /* */
object->module_id = (void *)module;
}
else
#endif
{
/* insert object into information object list */ /* 第四步:对象实例插入到对象容器对应的链表中 */
rt_list_insert_after(&(information->object_list), &(object->list)); /* 链表头插入对象 */
}
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
}
例如:初始化一个软件定时器对象,把实例对象链接到对象容器中
rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);
函数功能:该函数将从对象管理器中脱离一个静态的对象,但是该静态对象并不会被释放。
函数内容:
函数应用:核心代码
/**
* 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)
{
register rt_base_t temp;
/* object check */
RT_ASSERT(object != RT_NULL);
RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
/* reset object type */
object->type = 0; /* 复位对象类型 */
/* lock interrupt */
temp = rt_hw_interrupt_disable();
/* remove from old list */
rt_list_remove(&(object->list)); /* 从链表中删除对象节点 */
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
}
例如:
rt_object_detach((rt_object_t)timer);
函数功能:此函数将判断对象是否为系统对象。
函数内容:通常,系统对象是静态对象, 对象类型设置为RT_Object_Class_Static。
函数应用:通常,应用在断言函数中
/**
* This function will judge the object is system object or not.
* Normally, the system object is a static object and the type
* of object set to RT_Object_Class_Static.
*
* @param object 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;
}
例如:
RT_ASSERT(rt_object_is_systemobject(&timer->parent));
函数功能:此函数将返回没有RT_Object_Class_Static标志的对象类型。
函数内容:无
函数应用:通常,应用在断言函数中
/**
* This function will return the type of object without
* RT_Object_Class_Static flag.
*
* @param object 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;
}
例如:
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
函数功能:根据指定对象类型、名字,从对象容器链表中找到对应对象实例的地址
函数内容:无
函数应用:内核代码无调用
/**
* This function will find specified name object from object
* container.
*
* @param name the specified name of object.
* @param type 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;
/* parameter check */
if ((name == RT_NULL) || (type > RT_Object_Class_Unknown))
return RT_NULL;
/* which is invoke in interrupt status */
RT_DEBUG_NOT_IN_INTERRUPT;
/* enter critical */
rt_enter_critical();
/* try to find object */
if (information == RT_NULL)
{
information = rt_object_get_information((enum rt_object_class_type)type); /* 获取这一类对象的链表头 */
RT_ASSERT(information != RT_NULL);
}
for (node = information->object_list.next; /* 遍历对象链表节点 */
node != &(information->object_list);
node = node->next)
{
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;
}
微信公众号:萤火虫的电子笔记
分享电子产品开发软、硬件方面知识,51单片机、STM32、ARM、AltiumDesigner PCB设计、开发平台、软件工具等知识分享。
欢迎转发,请注明出处及作者。关注微信公众号,获取最新文章动态。