rt-thread采用内核对象管理系统来访问和管理所有内核对象.首先来看看rt-thread的内核对象是如何定义的:
1 数据结构
1.1 对象控制块
在include/rtdef.h头文件中可以找到内核对象有结构定义:
-
-
-
- struct rt_object
- {
- char name[RT_NAME_MAX];
- rt_uint8_t type;
- rt_uint8_t flag;
-
- #ifdef RT_USING_MODULE
- void *module_id;
- #endif
- rt_list_t list;
- };
- typedef struct rt_object *rt_object_t;
这里需要注意地是,上述内核对象控制块包含了一rt_list_t类型的成员list,这个是一链表节点,便于将此内核对象加入到一链表中,其结构如下定义:
- struct rt_list_node
- {
- struct rt_list_node *next;
- struct rt_list_node *prev;
- };
- typedef struct rt_list_node rt_list_t;
另内核对象类型取值有如下类型:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- enum rt_object_class_type
- {
- RT_Object_Class_Thread = 0,
- #ifdef RT_USING_SEMAPHORE
- RT_Object_Class_Semaphore,
- #endif
- #ifdef RT_USING_MUTEX
- RT_Object_Class_Mutex,
- #endif
- #ifdef RT_USING_EVENT
- RT_Object_Class_Event,
- #endif
- #ifdef RT_USING_MAILBOX
- RT_Object_Class_MailBox,
- #endif
- #ifdef RT_USING_MESSAGEQUEUE
- RT_Object_Class_MessageQueue,
- #endif
- #ifdef RT_USING_MEMHEAP
- RT_Object_Class_MemHeap,
- #endif
- #ifdef RT_USING_MEMPOOL
- RT_Object_Class_MemPool,
- #endif
- #ifdef RT_USING_DEVICE
- RT_Object_Class_Device,
- #endif
- RT_Object_Class_Timer,
- #ifdef RT_USING_MODULE
- RT_Object_Class_Module,
- #endif
- RT_Object_Class_Unknown,
- RT_Object_Class_Static = 0x80
- };
需要注意的是,rt-thread将内核对象的type的最高位若为1,则表示此内核对象为系统内核对象,否则非系统内核对象.
1.2 内核对象容器
RTT使用内核对象容器来管理同一类型的内核对象,并将其放入同一链表中,便于访问.内核对象信息的结构如下定义:
-
-
-
- struct rt_object_information
- {
- enum rt_object_class_type type;
- rt_list_t object_list;
- rt_size_t object_size;
- };
1.3 内核对象管理系统
RTT中,每一类型的内核对象都会有一内核对象容器来包容,这个类型的内核对象容器实际上是用一链表(见1.2节所示的内核对象容器结构定义),这个链表将所有相同类型的内核对象链接起来.由于每一类型都对应着有一个这样的内核对象容器来管理,那么所有内核对象容器整体就叫做内核对象管理系统.
如下图示:
RTT中,内核对象管理系统是用一个rt_object_information数组来实现的,如下:
- #define _OBJ_CONTAINER_LIST_INIT(c)\//内核对象容器的链表初始化,这里用一个宏来定义,链表的前一节点和后一节点在初始化时都指向本身所在地址
- {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}
-
-
- struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =
- {
- )},
- {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Thread), sizeof(struct rt_thread#ifdef RT_USING_SEMAPHORE
- //信号量对象信息
- {RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Semaphore), sizeof(struct rt_semaphore)},
- #endif
- #ifdef RT_USING_MUTEX
- //互斥锁对象信息
- {RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Mutex), sizeof(struct rt_mutex)},
- #endif
- #ifdef RT_USING_EVENT
- //事件对象信息
- {RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Event), sizeof(struct rt_event)},
- #endif
- #ifdef RT_USING_MAILBOX
- //邮箱对象信息
- {RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MailBox), sizeof(struct rt_mailbox)},
- #endif
- #ifdef RT_USING_MESSAGEQUEUE
- //消息队列对象信息
- {RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MessageQueue), sizeof(struct rt_messagequeue)},
- #endif
- #ifdef RT_USING_MEMHEAP
- //内存堆对象信息
- {RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemHeap), sizeof(struct rt_memheap)},
- #endif
- #ifdef RT_USING_MEMPOOL
- //内存池对象信息
- {RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemPool), sizeof(struct rt_mempool)},
- #endif
- #ifdef RT_USING_DEVICE
- //设备驱动对象信息
- {RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Device), sizeof(struct rt_device)},
- #endif
- //时钟对象信息
- {RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Timer), sizeof(struct rt_timer)},
- #ifdef RT_USING_MODULE
- //模块对象信息
- {RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Module), sizeof(struct rt_module)},
- #endif
- };
2 内核对象接口
2.1 内核对象初始化
RTT提供静态和动态两种初始化接口,如下:
静态初始化是将一个已经存在的且占有内存空间的对象初始化,它的接口如下:
-
-
-
-
-
-
-
-
- void rt_object_init(struct rt_object *object,
- enum rt_object_class_type type,
- const char *name)
- {
- register rt_base_t temp;
- struct rt_object_information *information;
-
- #ifdef RT_USING_MODULE //如果使用了模块,那么对象容器指向本线程所包含的对象窗口,否则指向全局对象管理系统中对应的容器
-
- information = (rt_module_self() != RT_NULL) ?
- &rt_module_self()->module_object[type] : &rt_object_container[type];
- #else
-
- information = &rt_object_container[type];
- #endif
-
-
-
-
- object->type = type | RT_Object_Class_Static;
-
-
- rt_strncpy(object->name, name, RT_NAME_MAX);
-
- RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
-
-
- temp = rt_hw_interrupt_disable();
-
-
- rt_list_insert_after(&(information->object_list), &(object->list));
-
-
- rt_hw_interrupt_enable(temp);
- }
动态初始化是指对象原本并不存在,在不内存中,需要动态为其分配内存,其接口如下:
-
-
-
-
-
-
-
-
- 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;
-
- RT_DEBUG_NOT_IN_INTERRUPT;
-
- #ifdef RT_USING_MODULE//同上面那个接口一样,获取对象容器
-
-
-
-
- information = (rt_module_self() != RT_NULL && (type != RT_Object_Class_Module)) ?
- &rt_module_self()->module_object[type] : &rt_object_container[type];
- #else
-
- information = &rt_object_container[type];
- #endif
-
- object = (struct rt_object *)rt_malloc(information->object_size);
- if (object == RT_NULL)
- {
-
- return RT_NULL;
- }
-
-
-
-
- object->type = type;
-
-
- object->flag = 0;
-
- #ifdef RT_USING_MODULE
- if (rt_module_self() != RT_NULL)
- {
- object->flag |= RT_OBJECT_FLAG_MODULE;
- }
- object->module_id = (void *)rt_module_self();
- #endif
-
-
- rt_strncpy(object->name, name, RT_NAME_MAX);
-
- RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
-
-
- temp = rt_hw_interrupt_disable();
-
-
- rt_list_insert_after(&(information->object_list), &(object->list));
-
-
- rt_hw_interrupt_enable(temp);
-
-
- return object;
- }
2.2 脱离或删除对象
如果对象是静态初始化的,那么对应的是脱离,如果是动态初始化的,则是删除.
脱离接口如下:
-
-
-
-
-
-
- void rt_object_detach(rt_object_t object)
- {
- register rt_base_t temp;
-
-
- RT_ASSERT(object != RT_NULL);
-
- RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
-
- temp = rt_hw_interrupt_disable();
-
-
- rt_list_remove(&(object->list));
-
-
- rt_hw_interrupt_enable(temp);
- }
删除接口如下:
-
-
-
-
-
- void rt_object_delete(rt_object_t object)
- {
- register rt_base_t temp;
-
-
- RT_ASSERT(object != RT_NULL);
- RT_ASSERT(!(object->type & RT_Object_Class_Static));
- RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
-
-
- temp = rt_hw_interrupt_disable();
-
-
- rt_list_remove(&(object->list));
-
-
- rt_hw_interrupt_enable(temp);
-
- #if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)//如果使用了模块功能且采用的是SLAB动态内存管理模式
- if (object->flag & RT_OBJECT_FLAG_MODULE)
- rt_module_free((rt_module_t)object->module_id, object);
- else
- #endif
-
-
- rt_free(object);
- }
其中rt_list_remove会自动找到对象的前一节点和后一节点,然后删除本身节点.
2.3 判断是否为系统内核对象
-
-
-
-
-
-
-
-
-
- rt_bool_t rt_object_is_systemobject(rt_object_t object)
- {
-
- RT_ASSERT(object != RT_NULL);
-
- if (object->type & RT_Object_Class_Static)
- return RT_TRUE;
-
- return RT_FALSE;
- }
2.4 查找内核对象
-
-
-
-
-
-
-
-
-
-
-
-
- rt_object_t rt_object_find(const char *name, rt_uint8_t type)
- {
- struct rt_object *object;
- struct rt_list_node *node;
- struct rt_object_information *information;
- extern volatile rt_uint8_t rt_interrupt_nest;
-
- //输入系统检查
- if ((name == RT_NULL) || (type > RT_Object_Class_Unknown))
- return RT_NULL;
-
-
- if (rt_interrupt_nest != 0)
- RT_ASSERT(0);
-
-
- rt_enter_critical();
-
-
- information = &rt_object_container[type];
- 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)
- {
-
- rt_exit_critical();
-
- return object;
- }
- }
-
-
- rt_exit_critical();
-
- return RT_NULL;
- }
3 内核对象系统初始化
-
-
-
-
-
-
-
-
- void rt_system_object_init(void)
- {
- }
从源代码可以看出,自从0.3.0以后,RTT就已经没有必须再使用此接口来对内核对象初始化了,因此,此函数是空的,但在系统初始化时还会保留调用些函数.