1、什么是对象
在RT-Thread,所有的数据结构都成为对象。
其中线程,信号量、互斥量、事件、邮箱、消息队列、内存堆、内存池、设备和定时器在rtdef.h中有明显的枚举定义,即为每个对象打上一个数字标签。
enum rt_object_class_type { RT_Object_Class_Thread = 0, /* 对象是线程 */ RT_Object_Class_Semaphore, /* 对象是信号量 */ RT_Object_Class_Mutex, /* 对象是互斥量 */ RT_Object_Class_Event, /* 对象是事件 */ RT_Object_Class_MailBox, /* 对象是邮箱 */ RT_Object_Class_MessageQueue, /* 对象是消息队列 */ RT_Object_Class_MemHeap, /* 对象是内存堆 */ RT_Object_Class_MemPool, /* 对象是内存池 */ RT_Object_Class_Device, /* 对象是设备 */ RT_Object_Class_Timer, /* 对象是定时器 */ RT_Object_Class_Module, /* 对象是模块 */ RT_Object_Class_Unknown, /* 对象未知 */ RT_Object_Class_Static = 0x80 /* 对象是静态对象 */ };
2、对象数据类型定义
在rtt中,为了方便管理这些对象,专门定义了一个对象类型的数据结构。具体如下:
struct rt_object { char name[RT_NAME_MAX]; (1) /* 内核对象的名字 */ rt_uint8_t type; (2) /* 内核对象的类型 */ rt_uint8_t flag; (3) /* 内核对象的状态 */ rt_list_t list; (4) /* 内核对象的列表节点 */ }; typedef struct rt_object *rt_object_t; (5) /* 内核对象数据类型重定义 */
(1)对象名字,字符串形式,方便调试,最大长度由rt_config.h中的宏RT_NAMA_MAX决定,默认定义为8。
(2)对象的类型,RT-Thread为每个对象都打上了数字标签,取值由rt_object_class_type枚举类型限定。
(3)对象的状态
(4)对象的列表节点,每个对象都可以通过自己的列表节点list将自己挂到列表容器中。
(5)对象的数据类型,RT-Thread中会为每一个新的结构体用typedef重定义一个指针类型的数据结构。
3、在线程控制块中添加对象成员
在RT-Thread中,每个对象都有对应的一个结构体,这个结构体叫做该对象的控制块。如线程会有一个线程控制块,定时器有一个定时器控制块,信号量有信号量控制块等。这些控制块的开头都会包含一个内核对象结构体。或者直接将对象结构体的成员放在对象控制块结构体的开头。其中线程控制块的开头放置的就是对象结构体的成员,具体如下:开头的高亮部分代码,这里我们只讲解往线程控制块里面添加对象结构体成员,其他内核对象的都是直接在其开头使用struct rt_object 直接定义一个内核对象变量。
4、什么是容器
在rtt中,每当用户创建一个对象,如线程,就会将这个对象放到一个叫做容器的地方,这样做得目的是为了方便管理,这时用户会问,管理什么?在RT-Thread 的组件finsh使用中,就需要使用到容器,通过扫描容器的内核对象来获取各个内核对象的状态,然后输出调试信息。目前,我们只需要知道所有创建的对象都会放到容器中。
那什么是容器,从代码上看,容器是一个数组,是一个全局变量,数据类型为 struct rt_object_information,在object.c中定义。