[RT-Thread 源码分析] 3. 内核对象管理

RTT在设计时虽然采用了c语言,但使用了面向对象的思想。所有的线程、事件设备等都是继承自object,且采用链表的方式统一管理。如图所示。

对象控制块
    /** 
     * Base structure of Kernel object 
     */  
    struct rt_object  
    {  
        char       name[RT_NAME_MAX];   // 名称  
        rt_uint8_t type;                // 内核对象类型   
        rt_uint8_t flag;                // 内核对象标志          
      
    #ifdef RT_USING_MODULE  
        void      *module_id;           // 模块ID  
    #endif  
        rt_list_t  list;                // 内核对象链表节点  
    };  
    typedef struct rt_object *rt_object_t;  
在内核里,所有对象都由链表组织起来。链表定义如下:
    struct rt_list_node  
    {  
        struct rt_list_node *next; // 指向下一节点  
        struct rt_list_node *prev; // 指向前一节点  
    };  
    typedef struct rt_list_node rt_list_t;     
所有可能派生出来的对象为:
    /** 
     *  The object type can be one of the follows with specific 
     *  macros enabled: 
     *  - Thread 
     *  - Semaphore 
     *  - Mutex 
     *  - Event 
     *  - MailBox 
     *  - MessageQueue 
     *  - MemHeap 
     *  - MemPool 
     *  - Device 
     *  - Timer 
     *  - Module 
     *  - Unknown 
     *  - Static 
     */  
    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以此位标志是否为系统内核对象  
    };      
所有对象又被放置于对象容器中:
    /** 
     * The information of the kernel object 
     */  
    struct rt_object_information  
    {  
        enum rt_object_class_type type;          // 内核对象类型  
        rt_list_t                 object_list;   // 内核对象链表  
        rt_size_t                 object_size;   // 内核对象所占的大小  
    };   
    
RTT中,内核对象管理系统是用一个rt_object_information数组来实现的,如下:
    #define _OBJ_CONTAINER_LIST_INIT(c)\
    // 内核对象容器的链表初始化,这里用一个宏来定义,链表的前一节点和后一节点在初始化时都指向本身所在地址  
        {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}  
      
    //内核对象管理系统,这里用rt_object_information数组来实现  
    struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =  
    {  
        /* initialize object container - thread */)},//线程对象信息  
        {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Thread), sizeof(struct rt_thread#ifdef RT_USING_SEMAPHORE  
        /* initialize object container - semaphore *///信号量对象信息  
        {RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Semaphore), sizeof(struct rt_semaphore)},  
    #endif  
    #ifdef RT_USING_MUTEX  
        /* initialize object container - mutex *///互斥锁对象信息  
        {RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Mutex), sizeof(struct rt_mutex)},  
    #endif  
    #ifdef RT_USING_EVENT  
        /* initialize object container - event *///事件对象信息  
        {RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Event), sizeof(struct rt_event)},  
    #endif  
    #ifdef RT_USING_MAILBOX  
        /* initialize object container - mailbox *///邮箱对象信息  
        {RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MailBox), sizeof(struct rt_mailbox)},  
    #endif  
    #ifdef RT_USING_MESSAGEQUEUE  
        /* initialize object container - message queue *///消息队列对象信息  
        {RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MessageQueue), sizeof(struct rt_messagequeue)},  
    #endif  
    #ifdef RT_USING_MEMHEAP  
        /* initialize object container - memory heap *///内存堆对象信息  
        {RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemHeap), sizeof(struct rt_memheap)},  
    #endif  
    #ifdef RT_USING_MEMPOOL  
        /* initialize object container - memory pool *///内存池对象信息  
        {RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemPool), sizeof(struct rt_mempool)},  
    #endif  
    #ifdef RT_USING_DEVICE  
        /* initialize object container - device *///设备驱动对象信息  
        {RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Device), sizeof(struct rt_device)},  
    #endif  
        /* initialize object container - timer *///时钟对象信息  
        {RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Timer), sizeof(struct rt_timer)},  
    #ifdef RT_USING_MODULE  
        /* initialize object container - module *///模块对象信息  
        {RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Module), sizeof(struct rt_module)},  
    #endif  
    };  
 
1. 内核对象初始化
=====
初始化分为静态和动态,区别主要静态是编译时确定,线程栈就在堆栈上,而动态则是运行时确定,其栈在堆上。
    /** 
     * 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_object_information *information;      // 对象容器  
      
    #ifdef RT_USING_MODULE  
        /* get module object information */  
        information = (rt_module_self() != RT_NULL) ?   
            &rt_module_self()->module_object[type] : &rt_object_container[type];  
    #else  
        /* get object information */ 
        // 从对象容器数组中,获取该类对象的链表信息
        information = &rt_object_container[type];  
    #endif  
      
        /* 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); 
      
        RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));  
      
        /* lock interrupt */
        // 禁中断
        temp = rt_hw_interrupt_disable(); 
      
        /* insert object into information object list */  
        // 将新对象插入当前对象容器中的链表
        rt_list_insert_after(&(information->object_list), &(object->list)); 
      
        /* unlock interrupt */  
        // 开中断
        rt_hw_interrupt_enable(temp);
    } 

2. 线程脱离    
/**
 * 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));

    /* lock interrupt */
    temp = rt_hw_interrupt_disable();

    /* remove from old list */
    // 将对象从链表中删除
    // 因为这是静态的对象方法,所以并不是真正的将对象删除,只是将其移除链表
    // 其所占的内存空间也不会回收
    rt_list_remove(&(object->list));

    /* unlock interrupt */
    rt_hw_interrupt_enable(temp);
}    

3. 动态初始化
=====
#ifdef RT_USING_HEAP
/**
 * This function will allocate an object from object system
 *
 * @param type the type of object
 * @param name 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;
    register rt_base_t temp;
    struct rt_object_information *information;

    RT_DEBUG_NOT_IN_INTERRUPT;

#ifdef RT_USING_MODULE
    /*
     * get module object information,
     * module object should be managed by kernel object container
     */
    information = (rt_module_self() != RT_NULL && (type != RT_Object_Class_Module)) ?
                  &rt_module_self()->module_object[type] : &rt_object_container[type];
#else
    /* get object information */
    information = &rt_object_container[type];
#endif

    object = (struct rt_object *)rt_malloc(information->object_size);
    // 按照其所要求的空间在heap上动态分配内存空间
    if (object == RT_NULL)
    {
        /* no memory can be allocated */
        return RT_NULL;
    }
    // 其后的步骤就和静态类似
    
    /* initialize object's parameters */

    /* set object type */
    object->type = type;

    /* set object flag */
    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

    /* copy name */
    rt_strncpy(object->name, name, RT_NAME_MAX);

    RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));

    /* lock interrupt */
    temp = rt_hw_interrupt_disable();

    /* 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;
}

4. 动态线程删除
=====
/**
 * This function will delete an object and release object memory.
 *
 * @param object the specified object to be deleted.
 */
void rt_object_delete(rt_object_t object)
{
    register rt_base_t temp;

    /* object check */
    RT_ASSERT(object != RT_NULL);
    RT_ASSERT(!(object->type & RT_Object_Class_Static));
    // 断言,确保不是静态

    RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));

    /* lock interrupt */
    temp = rt_hw_interrupt_disable();

    /* remove from old list */
    // 首先从链表中删除
    rt_list_remove(&(object->list));

    /* unlock interrupt */
    rt_hw_interrupt_enable(temp);

#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)
    if (object->flag & RT_OBJECT_FLAG_MODULE) 
        rt_module_free((rt_module_t)object->module_id, object);
    else
#endif

    /* free the memory of object */
    // 由于是动态,还需释放其所占的空间
    rt_free(object);
}
#endif



posted @ 2013-04-22 11:09  lyyyuna  阅读(475)  评论(0编辑  收藏  举报