内核对象

内核对象管理架构

RT-Thread 采用内核对象管理系统来访问 / 管理所有内核对象,内核对象包含了内核中绝大部分设施,这些内核对象可以是静态分配的静态对象,也可以是从系统内存堆中分配的动态对象。

通过这种内核对象的设计方式,RT-Thread 做到了不依赖于具体的内存分配方式,系统的灵活性得到极大的提高。

RT-Thread 内核对象包括:线程,信号量,互斥量,事件,邮箱,消息队列和定时器,内存池,设备驱动等。对象容器中包含了每类内核对象的信息,包括对象类型,大小等。对象容器给每类内核对象分配了一个链表,所有的内核对象都被链接到该链表上,RT-Thread 的内核对象容器及链表如下图所示:

下图则显示了 RT-Thread 中各类内核对象的派生和继承关系。对于每一种具体内核对象和对象控制块,除了基本结构外,还有自己的扩展属性(私有属性),例如,对于线程控制块,在基类对象基础上进行扩展,增加了线程状态、优先级等属性。这些属性在基类对象的操作中不会用到,只有在与具体线程相关的操作中才会使用。因此从面向对象的观点,可以认为每一种具体对象是抽象对象的派生,继承了基本对象的属性并在此基础上扩展了与自己相关的属性。

在对象管理模块中,定义了通用的数据结构,用来保存各种对象的共同属性,各种具体对象只需要在此基础上加上自己的某些特别的属性,就可以清楚的表示自己的特征。

这种设计方法的优点有:

(1)提高了系统的可重用性和扩展性,增加新的对象类别很容易,只需要继承通用对象的属性再加少量扩展即可。

(2)提供统一的对象操作方式,简化了各种具体对象的操作,提高了系统的可靠性。

上图中由对象控制块 rt_object 派生出来的有:线程对象、内存池对象、定时器对象、设备对象和 IPC 对象(IPC:Inter-Process Communication,进程间通信。在 RT-Thread 实时操作系统中,IPC 对象的作用是进行线程间同步与通信);由 IPC 对象派生出信号量、互斥量、事件、邮箱与消息队列、信号等对象。

对象控制块

内核对象控制块的数据结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

struct rt_object

{

/* 内核对象名称 */

char name[RT_NAME_MAX];

/* 内核对象类型 */

rt_uint8_t type;

/* 内核对象的参数 */

rt_uint8_t flag;

/* 内核对象管理链表 */

rt_list_t list;

};

目前内核对象支持的类型如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

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_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 /* 对象为静态对象 */

};

从上面的类型说明,我们可以看出,如果是静态对象,那么对象类型的最高位将是 1(是 RT_Object_Class_Static 与其他对象类型的或操作),否则就是动态对象,系统最多能够容纳的对象类别数目是 127 个。

内核对象管理方式

内核对象容器的数据结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

struct rt_object_information

{

/* 对象类型 */

enum rt_object_class_type type;

/* 对象链表 */

rt_list_t object_list;

/* 对象大小 */

rt_size_t object_size;

};

一类对象由一个 rt_object_information 结构体来管理,每一个这类对象的具体实例都通过链表的形式挂接在 object_list 上。而这一类对象的内存块尺寸由 object_size 标识出来(每一类对象的具体实例,他们占有的内存块大小都是相同的)。