# 作業系統工程-Object
# Table Of Content
###### tags: `作業系統工程 Operating System Programming note`, `110-1`, `2021`
[TOC]
---
# Concept
## Object 的概念

- 上圖表示,kernel 中所有不同的 object,都是從 base object 進行衍伸的。
- 好處是提高系統的可重用性和擴展性
- 即增加新的對像類別很容易,只要繼承 base object 的 attribute 再加一些擴展的 attribute 就好。
## 實作方式

- 用 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)