# 作業系統工程-Object # Table Of Content ###### tags: `作業系統工程 Operating System Programming note`, `110-1`, `2021` [TOC] --- # Concept ## Object 的概念 ![](https://i.imgur.com/lfIIFwP.png) - 上圖表示,kernel 中所有不同的 object,都是從 base object 進行衍伸的。 - 好處是提高系統的可重用性和擴展性 - 即增加新的對像類別很容易,只要繼承 base object 的 attribute 再加一些擴展的 attribute 就好。 ## 實作方式 ![](https://i.imgur.com/8uaSE8Z.png) - 用 array 當成不同 object 的頭 - 再將不同 object,其相同類別的 object 串在 array(頭) 的後面 # Coding ## Object Structure ```c= struct rt_object { char name[RT_NAME_MAX]; /* kernel object 的名稱 */ rt_uint8_t type; /* kernel object 的類型 */ rt_uint8_t flag; /* kernel object 的參數 */ rt_list_t list; /* kernel object's list*/ #ifdef RT_USING_MODULE void *module_id; /* id of application module */ #endif }; typedef struct rt_object *rt_object_t;/*Yype for kernel objects. */ ``` ## Object Class Type - 下面這些為 kernel object 可以使用的 type ```c= enum rt_object_class_type { RT_Object_Class_Null = 0x00, /* object is not used. */ RT_Object_Class_Thread = 0x01, /* object is a thread. */ RT_Object_Class_Semaphore = 0x02, /* object is a semaphore. */ RT_Object_Class_Mutex = 0x03, /* object is a mutex. */ RT_Object_Class_Event = 0x04, /* object is a event. */ RT_Object_Class_MailBox = 0x05, /* object is a mail box. */ RT_Object_Class_MessageQueue = 0x06, /* object is a message queue. */ RT_Object_Class_MemHeap = 0x07, /* object is a memory heap. */ RT_Object_Class_MemPool = 0x08, /* object is a memory pool. */ RT_Object_Class_Device = 0x09, /* object is a device. */ RT_Object_Class_Timer = 0x0a, /* object is a timer. */ RT_Object_Class_Module = 0x0b, /* object is a module. */ RT_Object_Class_Memory = 0x0c, /* object is a memory. */ RT_Object_Class_Unknown = 0x0e, /* object is unknown. */ RT_Object_Class_Static = 0x80 /* object is a static object. */ }; ``` - 所以如果是==靜態 object==,那麼 ==**Object Type 的最高位是 1**== ## Object Information - information 會記錄 1. Object Class Type(參考上方**enum rt_object_class_type**) 2. 此 object 的 linker list 3. 此 object 的容量大小多大 ```c= struct rt_object_information { enum rt_object_class_type type;/* object class type */ rt_list_t object_list; /* object list */ rt_size_t object_size; /* object size */ }; ``` ### rt_object_get_type() - 用此 function 可以得到回傳值的 object type。 ```c= rt_uint8_t rt_object_get_type(rt_object_t object) { RT_ASSERT(object != RT_NULL);/* object check */ return object->type & ~RT_Object_Class_Static; } ``` ## Object 提供的 base operation ### void rt_object_init() --初始化 - 在使用未初始化的靜態 object 前,必須先對其進行初始化。 ```c= void rt_object_init(struct rt_object *object, enum rt_object_class_type type, const char *name) { register rt_base_t temp; struct rt_list_node *node = RT_NULL; struct rt_object_information *information; #ifdef RT_USING_MODULE struct rt_dlmodule *module = dlmodule_self(); #endif /* RT_USING_MODULE */ /* get object information */ information = rt_object_get_information(type); RT_ASSERT(information != RT_NULL); /* check object type to avoid re-initialization */ /* enter critical */ rt_enter_critical(); /* try to find object */ for (node = information->object_list.next; node != &(information->object_list); node = node->next) { struct rt_object *obj; obj = rt_list_entry(node, struct rt_object, list); if (obj) /* skip warning when disable debug */ RT_ASSERT(obj != object); } /* leave critical */ rt_exit_critical(); /* initialize object's parameters */ object->type = type | RT_Object_Class_Static;/* set object type to static */ rt_strncpy(object->name, name, RT_NAME_MAX);/* copy name */ RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object)); /* lock interrupt */ temp = rt_hw_interrupt_disable(); #ifdef RT_USING_MODULE if (module) { rt_list_insert_after(&(module->object_list), &(object->list)); object->module_id = (void *)module; } else #endif /* RT_USING_MODULE */ { /* insert object into information object list */ rt_list_insert_after(&(information->object_list), &(object->list)); } /* unlock interrupt */ rt_hw_interrupt_enable(temp); } ``` ### void rt_object_detach(rt_object_t object) --靜態移除 object ```c= 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)); /* reset object type */ object->type = 0; /* lock interrupt */ temp = rt_hw_interrupt_disable(); /* remove from old list */ rt_list_remove(&(object->list)); /* unlock interrupt */ rt_hw_interrupt_enable(temp); } ``` ### rt_object_t rt_object_allocate() --動態配置 object ```c= 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; #ifdef RT_USING_MODULE struct rt_dlmodule *module = dlmodule_self(); #endif /* RT_USING_MODULE */ RT_DEBUG_NOT_IN_INTERRUPT; /* get object information */ information = rt_object_get_information(type); RT_ASSERT(information != RT_NULL); object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size); if (object == RT_NULL)//動態配置可能拿不到可以用的空間 return RT_NULL;/* no memory can be allocated */ /* clean memory data of object */ rt_memset(object, 0x0, information->object_size); /* initialize object's parameters */ object->type = type;/* set object type */ object->flag = 0;/* set object flag */ rt_strncpy(object->name, name, RT_NAME_MAX);/* copy name */ RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object)); /* lock interrupt */ temp = rt_hw_interrupt_disable(); #ifdef RT_USING_MODULE if (module) { rt_list_insert_after(&(module->object_list), &(object->list)); object->module_id = (void *)module; } else #endif /* RT_USING_MODULE */ { /* 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; } ``` ### void rt_object_delete(rt_object_t object) --動態刪除 object ```c= 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)); /* reset object type */ object->type = RT_Object_Class_Null; /* lock interrupt */ temp = rt_hw_interrupt_disable(); /* remove from old list */ rt_list_remove(&(object->list)); /* unlock interrupt */ rt_hw_interrupt_enable(temp); /* free the memory of object */ RT_KERNEL_FREE(object); } ``` # Example Of base Object & other object ## example 1 #### Base Object Structure ```c= struct rt_object { char name[RT_NAME_MAX];/*name of kernel object */ rt_uint8_t type; /*type of kernel object */ rt_uint8_t flag; /*flag of kernel object */ rt_list_t list; /*list node of kernel object */ #ifdef RT_USING_MODULE void *module_id; /*id of application module */ #endif }; typedef struct rt_object *rt_object_t;/* Type for kernel objects. */ ``` #### Timer Structure/ Expansion Object ```c= struct rt_timer { struct rt_object parent; /* inherit from rt_object */ rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL]; void (*timeout_func)(void *parameter);/* timeout function */ void *parameter; /* timeout function's parameter */ rt_tick_t init_tick; /* timer timeout tick */ rt_tick_t timeout_tick; /* timeout tick */ }; typedef struct rt_timer *rt_timer_t; ``` - Timer 的 line 3 表示 struct timer 繼承 struct object 的所有東西,並加上 line5~11 的東西 ## example 2 #### Base Object Structure ```c= struct rt_object { char name[RT_NAME_MAX];/*name of kernel object */ rt_uint8_t type; /*type of kernel object */ rt_uint8_t flag; /*flag of kernel object */ rt_list_t list; /*list node of kernel object */ #ifdef RT_USING_MODULE void *module_id; /*id of application module */ #endif }; typedef struct rt_object *rt_object_t;/* Type for kernel objects. */ ``` ```c= struct rt_ipc_object { struct rt_object parent; /* inherit from rt_object */ rt_list_t suspend_thread;/* threads pended on this resource */ }; ``` #### Mutex Structure ```c= struct rt_mutex { struct rt_ipc_object parent; /* inherit from ipc_object */ rt_uint16_t value; /* value of mutex */ rt_uint8_t original_priority;/* priority of last thread hold the mutex */ rt_uint8_t hold; /* numbers of thread hold the mutex */ struct rt_thread *owner; /* current owner of mutex */ }; typedef struct rt_mutex *rt_mutex_t; ``` - 因為 mutex 是 ipc 的一種方式,所以中間多繼承一層 ipc structure。 (ipc 都會到 hanging list)