内核对象管理架构--上
内核对象类型
线程、信号量、互斥量、事件、邮箱、消息队列、定时器、内存池、设备驱动等
位与rtdef.h中的对象类型定义
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. */
};
对象管理器
(实际上是一个数组),其中的元素是
/**
* 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_object_container , 位与object.c中
#define _OBJ_CONTAINER_LIST_INIT(c) \
{&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}
static struct rt_object_information rt_object_container[RT_Object_Info_Unknown] =
{
{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread)},
...
}
分析一下这个对象管理器数组,每个元素包括:1、对象类型,2、该类型对象(循环)链表,3、该类型对象的大小。其中 _OBJ_CONTAINER_LIST_INIT(c) 负责初始化一个循环链表,链表的元素为对象类型。(其中关于rtthread中的链表可见文章:占位符)
有个这些信息,可以大致将这个对象管理器画出来
各类型之间存在如下继承关系
给出一个例子:互斥量的创建
__ROM_USED rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
{
struct rt_mutex *mutex;
RT_DEBUG_NOT_IN_INTERRUPT;
/* allocate object */
mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name);
if (mutex == RT_NULL)
return mutex;
/* init ipc object */
rt_ipc_object_init(&(mutex->parent));
mutex->value = 1;
mutex->owner = RT_NULL;
mutex->original_priority = 0xFF;
mutex->hold = 0;
/* set flag */
mutex->parent.parent.flag = flag;
return mutex;
}
RTM_EXPORT(rt_mutex_create);
这个create负责创建动态创建一个互斥锁,来就看一下他都做了什么
1、创建一个对象 rt_object_allocate
mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name);
__ROM_USED rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{
struct rt_object *object;
register rt_base_t temp;
struct rt_object_information *information;
//1、从静态的对对象管理器数组中去除对应类型的元素
information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL);
//2、根据大小申请内存
object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
if (object == RT_NULL)
{
/* no memory can be allocated */
return RT_NULL;
}
//3、清空内存
/* clean memory data of object */
rt_memset(object, 0x0, information->object_size);
/* initialize object's parameters */
//4、为申请的内存赋值(类型、flag、name)
/* set object type */
object->type = type;
/* set object flag */
object->flag = 0;
/* copy name */
rt_strncpy(object->name, name, RT_NAME_MAX);
/* lock interrupt */
temp = rt_hw_interrupt_disable();
//5、将该节点插入到静态对象管理器数组上对应的链表中
/* insert object into information object list */
rt_list_insert_after(&(information->object_list), &(object->list));
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
/* return object */
return object;
}
第二步,初始化 特定链表,rt_ipc_object_init
这一步在每个类型对象中表现不一样,此处以ipc中的互斥量为例子
rt_ipc_object_init(&(mutex->parent));
rt_inline void rt_list_init(rt_list_t *l)
{
l->next = l->prev = l;
}
rt_inline rt_err_t rt_ipc_object_init(struct rt_ipc_object *ipc)
{
/* init ipc object */
rt_list_init(&(ipc->suspend_thread));
return RT_EOK;
}
到这里就不得不介绍一下 rt_mutex 结构体了
//互斥锁结构体
struct rt_ipc_object
{
struct rt_object parent; /**< inherit from rt_object */
rt_list_t suspend_thread; /**< threads pended on this resource */
};
//互斥锁结构体
struct rt_mutex
{
struct rt_ipc_object parent; /**< inherit from ipc_object */
rt_uint16_t value; /**< value of mutex */
rt_uint8_t original_priority; /**< priority of last thread hold the mutex */
rt_uint8_t hold; /**< numbers of thread hold the mutex */
struct rt_thread *owner; /**< current owner of mutex */
};
这里特殊一点的是 rt_mutex 结构体又包含了 rt_ipc_object 结构体,这里是因为将ipc对象的共有部分抽离了出来,(即一个阻塞线程队列)。
因此,这里所谓的初始化 特定链表,也是对该列表的初始化。
第三步、互斥锁赋值
mutex->value = 1;
mutex->owner = RT_NULL;
mutex->original_priority = 0xFF;
mutex->hold = 0;
/* set flag */
mutex->parent.parent.flag = flag;
这就没什么可说的了。
至此,就利用对象管理器数组创建了一个互斥锁对象