zoukankan      html  css  js  c++  java
  • [RTThread 源码分析] 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



  • 相关阅读:
    解决DataGridView中回车换行的问题
    几条经典的SQL语句
    SQL中把一个表中的数据导出到一个新表中
    [转载]TCP的网络编程中一些典型的问题,以及一些分析和解决方案
    Delphi调用C#web服务参数无法接收的问题
    IIS服务器不支持中文文件名的解决方法
    SQL SERVER2005导入导出工具
    为远程IP服务器取个本地认识的主机名
    Win Form中如何把ENter回车键转换成Tab键
    CheckedListBox 用法
  • 原文地址:https://www.cnblogs.com/lyyyuna/p/4123906.html
Copyright © 2011-2022 走看看