rt-thread的内核对象管理系统分析

rt-thread采用内核对象管理系统来访问和管理所有内核对象.首先来看看rt-thread的内核对象是如何定义的:

1 数据结构

1.1 对象控制块

在include/rtdef.h头文件中可以找到内核对象有结构定义:

[cpp]  view plain  copy
  1. /** 
  2.  * Base structure of Kernel object 
  3.  */  
  4. struct rt_object  
  5. {  
  6.     char       name[RT_NAME_MAX];//名称  
  7.     rt_uint8_t type;//内核对象类型   
  8.     rt_uint8_t flag;//内核对象标志          
  9.   
  10. #ifdef RT_USING_MODULE  
  11.     void      *module_id;//模块ID  
  12. #endif  
  13.     rt_list_t  list;//内核对象链表节点  
  14. };  
  15. typedef struct rt_object *rt_object_t;  


这里需要注意地是,上述内核对象控制块包含了一rt_list_t类型的成员list,这个是一链表节点,便于将此内核对象加入到一链表中,其结构如下定义:

[cpp]  view plain  copy
  1. struct rt_list_node  
  2. {  
  3.     struct rt_list_node *next; //指向下一节点  
  4.     struct rt_list_node *prev; //指向前一节点  
  5. };  
  6. typedef struct rt_list_node rt_list_t;  

 

另内核对象类型取值有如下类型:

[cpp]  view plain  copy
  1. /** 
  2.  *  The object type can be one of the follows with specific 
  3.  *  macros enabled: 
  4.  *  - Thread 
  5.  *  - Semaphore 
  6.  *  - Mutex 
  7.  *  - Event 
  8.  *  - MailBox 
  9.  *  - MessageQueue 
  10.  *  - MemHeap 
  11.  *  - MemPool 
  12.  *  - Device 
  13.  *  - Timer 
  14.  *  - Module 
  15.  *  - Unknown 
  16.  *  - Static 
  17.  */  
  18. enum rt_object_class_type  
  19. {  
  20.     RT_Object_Class_Thread = 0, //线程  
  21. #ifdef RT_USING_SEMAPHORE  
  22.     RT_Object_Class_Semaphore, //信号量  
  23. #endif  
  24. #ifdef RT_USING_MUTEX  
  25.     RT_Object_Class_Mutex,   //互斥锁  
  26. #endif  
  27. #ifdef RT_USING_EVENT  
  28.     RT_Object_Class_Event,  //事件  
  29. #endif  
  30. #ifdef RT_USING_MAILBOX  
  31.     RT_Object_Class_MailBox,  //邮箱  
  32. #endif  
  33. #ifdef RT_USING_MESSAGEQUEUE  
  34.     RT_Object_Class_MessageQueue,  //消息队列  
  35. #endif  
  36. #ifdef RT_USING_MEMHEAP  
  37.     RT_Object_Class_MemHeap,      //内存堆  
  38. #endif  
  39. #ifdef RT_USING_MEMPOOL  
  40.     RT_Object_Class_MemPool,     //内存池  
  41. #endif  
  42. #ifdef RT_USING_DEVICE  
  43.     RT_Object_Class_Device,     //设备驱动  
  44. #endif  
  45.     RT_Object_Class_Timer,      //时钟  
  46. #ifdef RT_USING_MODULE  
  47.     RT_Object_Class_Module,     //模块  
  48. #endif  
  49.     RT_Object_Class_Unknown,      //未知内核对象类型  
  50.     RT_Object_Class_Static = 0x80  //rt-thread以此位标志是否为系统内核对象  
  51. };  

需要注意的是,rt-thread将内核对象的type的最高位若为1,则表示此内核对象为系统内核对象,否则非系统内核对象.


 1.2 内核对象容器

RTT使用内核对象容器来管理同一类型的内核对象,并将其放入同一链表中,便于访问.内核对象信息的结构如下定义:

[cpp]  view plain  copy
  1. /** 
  2.  * The information of the kernel object 
  3.  */  
  4. struct rt_object_information  
  5. {  
  6.     enum rt_object_class_type type;          //内核对象类型  
  7.     rt_list_t                 object_list;   //内核对象链表  
  8.     rt_size_t                 object_size;   //内核对象所占的大小  
  9. };  


 1.3 内核对象管理系统

RTT中,每一类型的内核对象都会有一内核对象容器来包容,这个类型的内核对象容器实际上是用一链表(见1.2节所示的内核对象容器结构定义),这个链表将所有相同类型的内核对象链接起来.由于每一类型都对应着有一个这样的内核对象容器来管理,那么所有内核对象容器整体就叫做内核对象管理系统.

如下图示:


RTT中,内核对象管理系统是用一个rt_object_information数组来实现的,如下:

[cpp]  view plain  copy
  1. #define _OBJ_CONTAINER_LIST_INIT(c)\//内核对象容器的链表初始化,这里用一个宏来定义,链表的前一节点和后一节点在初始化时都指向本身所在地址  
  2.     {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}  
  3.   
  4. //内核对象管理系统,这里用rt_object_information数组来实现  
  5. struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =  
  6. {  
  7.     /* initialize object container - thread */)},//线程对象信息  
  8.     {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Thread), sizeof(struct rt_thread#ifdef RT_USING_SEMAPHORE  
  9.     /* initialize object container - semaphore *///信号量对象信息  
  10.     {RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Semaphore), sizeof(struct rt_semaphore)},  
  11. #endif  
  12. #ifdef RT_USING_MUTEX  
  13.     /* initialize object container - mutex *///互斥锁对象信息  
  14.     {RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Mutex), sizeof(struct rt_mutex)},  
  15. #endif  
  16. #ifdef RT_USING_EVENT  
  17.     /* initialize object container - event *///事件对象信息  
  18.     {RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Event), sizeof(struct rt_event)},  
  19. #endif  
  20. #ifdef RT_USING_MAILBOX  
  21.     /* initialize object container - mailbox *///邮箱对象信息  
  22.     {RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MailBox), sizeof(struct rt_mailbox)},  
  23. #endif  
  24. #ifdef RT_USING_MESSAGEQUEUE  
  25.     /* initialize object container - message queue *///消息队列对象信息  
  26.     {RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MessageQueue), sizeof(struct rt_messagequeue)},  
  27. #endif  
  28. #ifdef RT_USING_MEMHEAP  
  29.     /* initialize object container - memory heap *///内存堆对象信息  
  30.     {RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemHeap), sizeof(struct rt_memheap)},  
  31. #endif  
  32. #ifdef RT_USING_MEMPOOL  
  33.     /* initialize object container - memory pool *///内存池对象信息  
  34.     {RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemPool), sizeof(struct rt_mempool)},  
  35. #endif  
  36. #ifdef RT_USING_DEVICE  
  37.     /* initialize object container - device *///设备驱动对象信息  
  38.     {RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Device), sizeof(struct rt_device)},  
  39. #endif  
  40.     /* initialize object container - timer *///时钟对象信息  
  41.     {RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Timer), sizeof(struct rt_timer)},  
  42. #ifdef RT_USING_MODULE  
  43.     /* initialize object container - module *///模块对象信息  
  44.     {RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Module), sizeof(struct rt_module)},  
  45. #endif  
  46. };  


 2 内核对象接口

2.1 内核对象初始化

RTT提供静态和动态两种初始化接口,如下:

静态初始化是将一个已经存在的且占有内存空间的对象初始化,它的接口如下:

[cpp]  view plain  copy
  1. /** 
  2.  * This function will initialize an object and add it to object system 
  3.  * management. 
  4.  * 
  5.  * @param object the specified object to be initialized. 
  6.  * @param type the object type. 
  7.  * @param name the object name. In system, the object's name must be unique. 
  8.  */  
  9. void rt_object_init(struct rt_object         *object,//指向已存在的对象指针  
  10.                     enum rt_object_class_type type,  //对象的类型  
  11.                     const char               *name)  //对象的名字字符串  
  12. {  
  13.     register rt_base_t temp;  
  14.     struct rt_object_information *information;      //对象容器  
  15.   
  16. #ifdef RT_USING_MODULE //如果使用了模块,那么对象容器指向本线程所包含的对象窗口,否则指向全局对象管理系统中对应的容器  
  17.     /* get module object information */  
  18.     information = (rt_module_self() != RT_NULL) ?   
  19.         &rt_module_self()->module_object[type] : &rt_object_container[type];  
  20. #else  
  21.     /* get object information */  
  22.     information = &rt_object_container[type];  
  23. #endif  
  24.   
  25.     /* initialize object's parameters */  
  26.   
  27.     /* set object type to static */  
  28.     object->type = type | RT_Object_Class_Static;//设置系统对象标志  
  29.   
  30.     /* copy name */  
  31.     rt_strncpy(object->name, name, RT_NAME_MAX);//给名字赋值  
  32.   
  33.     RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));//使用钩子函数  
  34.   
  35.     /* lock interrupt */  
  36.     temp = rt_hw_interrupt_disable();//关中断  
  37.   
  38.     /* insert object into information object list */  
  39.     rt_list_insert_after(&(information->object_list), &(object->list));//将初始化的内核对象加入到对应容器中  
  40.   
  41.     /* unlock interrupt */  
  42.     rt_hw_interrupt_enable(temp);//开中断  
  43. }  

动态初始化是指对象原本并不存在,在不内存中,需要动态为其分配内存,其接口如下:


 

[cpp]  view plain  copy
  1. /** 
  2.  * This function will allocate an object from object system 
  3.  * 
  4.  * @param type the type of object 
  5.  * @param name the object name. In system, the object's name must be unique. 
  6.  * 
  7.  * @return object 
  8.  */  
  9. rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)//动态初始化接口只需要传入名字和类型  
  10. {  
  11.     struct rt_object *object;  
  12.     register rt_base_t temp;  
  13.     struct rt_object_information *information;//对象容器  
  14.   
  15.     RT_DEBUG_NOT_IN_INTERRUPT;  
  16.   
  17. #ifdef RT_USING_MODULE//同上面那个接口一样,获取对象容器  
  18.     /* 
  19.      * get module object information, 
  20.      * module object should be managed by kernel object container 
  21.      */  
  22.     information = (rt_module_self() != RT_NULL && (type != RT_Object_Class_Module)) ?  
  23.                   &rt_module_self()->module_object[type] : &rt_object_container[type];  
  24. #else  
  25.     /* get object information */  
  26.     information = &rt_object_container[type];  
  27. #endif  
  28.   
  29.     object = (struct rt_object *)rt_malloc(information->object_size);//为对象动态分配内存空间  
  30.     if (object == RT_NULL)  
  31.     {  
  32.         /* no memory can be allocated */  
  33.         return RT_NULL;  
  34.     }  
  35.       
  36.     /* initialize object's parameters */  
  37.   
  38.     /* set object type */  
  39.     object->type = type;//设置类型  
  40.   
  41.     /* set object flag */  
  42.     object->flag = 0;//设置标志为0  
  43.   
  44. #ifdef RT_USING_MODULE  
  45.     if (rt_module_self() != RT_NULL)  
  46.     {  
  47.         object->flag |= RT_OBJECT_FLAG_MODULE;//如果使用了模块功能,则将flag标志设置为模块标志  
  48.     }  
  49.     object->module_id = (void *)rt_module_self();//设置模块ID  
  50. #endif  
  51.   
  52.     /* copy name */  
  53.     rt_strncpy(object->name, name, RT_NAME_MAX);//给名称赋值  
  54.   
  55.     RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));//使用钩子函数  
  56.   
  57.     /* lock interrupt */  
  58.     temp = rt_hw_interrupt_disable();//关中断  
  59.   
  60.     /* insert object into information object list */  
  61.     rt_list_insert_after(&(information->object_list), &(object->list));//将此对象加入对应容器  
  62.   
  63.     /* unlock interrupt */  
  64.     rt_hw_interrupt_enable(temp);//关中断  
  65.   
  66.     /* return object */  
  67.     return object;  
  68. }  


 2.2 脱离或删除对象

如果对象是静态初始化的,那么对应的是脱离,如果是动态初始化的,则是删除.

脱离接口如下:

[cpp]  view plain  copy
  1. /** 
  2.  * This function will detach a static object from object system, 
  3.  * and the memory of static object is not freed. 
  4.  * 
  5.  * @param object the specified object to be detached. 
  6.  */  
  7. void rt_object_detach(rt_object_t object)  
  8. {  
  9.     register rt_base_t temp;  
  10.   
  11.     /* object check */  
  12.     RT_ASSERT(object != RT_NULL);  
  13.   
  14.     RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));//使用钩子函数  
  15.     /* lock interrupt */  
  16.     temp = rt_hw_interrupt_disable();//关中断  
  17.   
  18.     /* remove from old list */  
  19.     rt_list_remove(&(object->list));//从窗口中移除  
  20.   
  21.     /* unlock interrupt */  
  22.     rt_hw_interrupt_enable(temp);//开中断  
  23. }  

删除接口如下:


 

[cpp]  view plain  copy
  1. /** 
  2.  * This function will delete an object and release object memory. 
  3.  * 
  4.  * @param object the specified object to be deleted. 
  5.  */  
  6. void rt_object_delete(rt_object_t object)  
  7. {  
  8.     register rt_base_t temp;  
  9.   
  10.     /* object check */  
  11.     RT_ASSERT(object != RT_NULL);  
  12.     RT_ASSERT(!(object->type & RT_Object_Class_Static));//删除的对象必须是非系统对象  
  13.     RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));//使用钩子函数  
  14.   
  15.     /* lock interrupt */  
  16.     temp = rt_hw_interrupt_disable();//关中断  
  17.   
  18.     /* remove from old list */  
  19.     rt_list_remove(&(object->list));//从对应的容器中移除  
  20.   
  21.     /* unlock interrupt */  
  22.     rt_hw_interrupt_enable(temp);//开中断  
  23.   
  24. #if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)//如果使用了模块功能且采用的是SLAB动态内存管理模式  
  25.     if (object->flag & RT_OBJECT_FLAG_MODULE)   
  26.         rt_module_free((rt_module_t)object->module_id, object);//释放模块ID所占空间  
  27.     else  
  28. #endif  
  29.   
  30.     /* free the memory of object */  
  31.     rt_free(object);//释放内核对象所占空间  
  32. }  


 其中rt_list_remove会自动找到对象的前一节点和后一节点,然后删除本身节点.

2.3 判断是否为系统内核对象

[cpp]  view plain  copy
  1. /** 
  2.  * This function will judge the object is system object or not. 
  3.  * Normally, the system object is a static object and the type 
  4.  * of object set to RT_Object_Class_Static. 
  5.  * 
  6.  * @param object the specified object to be judged. 
  7.  * 
  8.  * @return RT_TRUE if a system object, RT_FALSE for others. 
  9.  */  
  10. rt_bool_t rt_object_is_systemobject(rt_object_t object)  
  11. {  
  12.     /* object check */  
  13.     RT_ASSERT(object != RT_NULL);  
  14.   
  15.     if (object->type & RT_Object_Class_Static)//RTT是通过内核对象的type的最高位是否为1来判断此对象是否为系统内核对象的  
  16.         return RT_TRUE;  
  17.   
  18.     return RT_FALSE;  
  19. }  

2.4  查找内核对象


 

[cpp]  view plain  copy
  1. /** 
  2.  * This function will find specified name object from object 
  3.  * container. 
  4.  * 
  5.  * @param name the specified name of object. 
  6.  * @param type the type of object 
  7.  * 
  8.  * @return the found object or RT_NULL if there is no this object 
  9.  * in object container. 
  10.  * 
  11.  * @note this function shall not be invoked in interrupt status. 
  12.  */  
  13. rt_object_t rt_object_find(const char *name, rt_uint8_t type)  
  14. {  
  15.     struct rt_object *object;  
  16.     struct rt_list_node *node;  
  17.     struct rt_object_information *information;  
  18.     extern volatile rt_uint8_t rt_interrupt_nest;  
  19.   
  20.     /* parameter check *///输入系统检查  
  21.     if ((name == RT_NULL) || (type > RT_Object_Class_Unknown))  
  22.         return RT_NULL;  
  23.   
  24.     /* which is invoke in interrupt status */  
  25.     if (rt_interrupt_nest != 0)//确保当前没有中断嵌套  
  26.         RT_ASSERT(0);  
  27.   
  28.     /* enter critical */  
  29.     rt_enter_critical();//进入临界区  
  30.   
  31.     /* try to find object */  
  32.     information = &rt_object_container[type];//获取对应的对象容器  
  33.     for (node  = information->object_list.next;//开始通过名字来扫描内核对象  
  34.          node != &(information->object_list);  
  35.          node  = node->next)  
  36.     {  
  37.         object = rt_list_entry(node, struct rt_object, list);//获取内核对象  
  38.         if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)//判断名字是否相符  
  39.         {  
  40.             /* leave critical */  
  41.             rt_exit_critical();//退出临界区  
  42.   
  43.             return object;  
  44.         }  
  45.     }  
  46.   
  47.     /* leave critical */  
  48.     rt_exit_critical();//退出临界区  
  49.   
  50.     return RT_NULL;  
  51. }  

 

3 内核对象系统初始化

[cpp]  view plain  copy
  1. /** 
  2.  * @ingroup SystemInit 
  3.  * 
  4.  * This function will initialize system object management. 
  5.  * 
  6.  * @deprecated since 0.3.0, this function does not need to be invoked 
  7.  * in the system initialization. 
  8.  */  
  9. void rt_system_object_init(void)  
  10. {  
  11. }  


从源代码可以看出,自从0.3.0以后,RTT就已经没有必须再使用此接口来对内核对象初始化了,因此,此函数是空的,但在系统初始化时还会保留调用些函数.

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值