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