程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> rt-thread的內核對象管理系統分析

rt-thread的內核對象管理系統分析

編輯:C++入門知識

rt-thread采用內核對象管理系統來訪問和管理所有內核對象.首先來看看rt-thread的內核對象是如何定義的: 1 數據結構 1.1 對象控制塊 在include/rtdef.h頭文件中可以找到內核對象有結構定義: [cpp]  /**   * 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;     這裡需要注意地是,上述內核對象控制塊包含了一rt_list_t類型的成員list,這個是一鏈表節點,便於將此內核對象加入到一鏈表中,其結構如下定義: [cpp]   struct rt_list_node   {       struct rt_list_node *next; //指向下一節點       struct rt_list_node *prev; //指向前一節點   };   typedef struct rt_list_node rt_list_t;     另內核對象類型取值有如下類型: [cpp]   /**   *  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以此位標志是否為系統內核對象   };   需要注意的是,rt-thread將內核對象的type的最高位若為1,則表示此內核對象為系統內核對象,否則非系統內核對象.    1.2 內核對象容器 RTT使用內核對象容器來管理同一類型的內核對象,並將其放入同一鏈表中,便於訪問.內核對象信息的結構如下定義: [cpp]  /**   * 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;   //內核對象所占的大小   };      1.3 內核對象管理系統 RTT中,每一類型的內核對象都會有一內核對象容器來包容,這個類型的內核對象容器實際上是用一鏈表(見1.2節所示的內核對象容器結構定義),這個鏈表將所有相同類型的內核對象鏈接起來.由於每一類型都對應著有一個這樣的內核對象容器來管理,那麼所有內核對象容器整體就叫做內核對象管理系統. RTT中,內核對象管理系統是用一個rt_object_information數組來實現的,如下: [cpp]   #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   };      2 內核對象接口 2.1 內核對象初始化 RTT提供靜態和動態兩種初始化接口,如下: 靜態初始化是將一個已經存在的且占有內存空間的對象初始化,它的接口如下: [cpp]   /**   * 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);//開中斷   }   動態初始化是指對象原本並不存在,在不內存中,需要動態為其分配內存,其接口如下:     [cpp]   /**   * 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);//為對象動態分配內存空間       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;//設置標志為0      #ifdef RT_USING_MODULE       if (rt_module_self() != RT_NULL)       {           object->flag |= RT_OBJECT_FLAG_MODULE;//如果使用了模塊功能,則將flag標志設置為模塊標志       }       object->module_id = (void *)rt_module_self();//設置模塊ID   #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;   }      2.2 脫離或刪除對象 如果對象是靜態初始化的,那麼對應的是脫離,如果是動態初始化的,則是刪除. 脫離接口如下: [cpp]  /**   * 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);//開中斷   }   刪除接口如下:     [cpp]   /**   * 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)//如果使用了模塊功能且采用的是SLAB動態內存管理模式       if (object->flag & RT_OBJECT_FLAG_MODULE)            rt_module_free((rt_module_t)object->module_id, object);//釋放模塊ID所占空間       else   #endif          /* free the memory of object */       rt_free(object);//釋放內核對象所占空間   }      其中rt_list_remove會自動找到對象的前一節點和後一節點,然後刪除本身節點. 1.3 判斷是否為系統內核對象 [cpp]   /**   * This function will judge the object is system object or not.   * Normally, the system object is a static object and the type   * of object set to RT_Object_Class_Static.   *   * @param object the specified object to be judged.   *   * @return RT_TRUE if a system object, RT_FALSE for others.   */   rt_bool_t rt_object_is_systemobject(rt_object_t object)   {       /* object check */       RT_ASSERT(object != RT_NULL);          if (object->type & RT_Object_Class_Static)//RTT是通過內核對象的type的最高位是否為1來判斷此對象是否為系統內核對象的           return RT_TRUE;          return RT_FALSE;   }   1.4  查找內核對象     [cpp]   /**   * This function will find specified name object from object   * container.   *   * @param name the specified name of object.   * @param type the type of object   *   * @return the found object or RT_NULL if there is no this object   * in object container.   *   * @note this function shall not be invoked in interrupt status.   */   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;          /* parameter check *///輸入系統檢查       if ((name == RT_NULL) || (type > RT_Object_Class_Unknown))           return RT_NULL;          /* which is invoke in interrupt status */       if (rt_interrupt_nest != 0)//確保當前沒有中斷嵌套           RT_ASSERT(0);          /* enter critical */       rt_enter_critical();//進入臨界區          /* try to find object */       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)//判斷名字是否相符           {               /* leave critical */               rt_exit_critical();//退出臨界區                  return object;           }       }          /* leave critical */       rt_exit_critical();//退出臨界區          return RT_NULL;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved