概述
什么是对象
在RT-Thread中,所有的数据结构都称之为对象
对象枚举定义
其中线程,信号量、互斥量、事件、邮箱、消息队列、内存堆、内存池、设备和定时器在rtdef.h中有明显的枚举定义,即为每个对象打上了一个数字标签。
enum rt_object_class_type
{
RT_Object_Class_Thread = 0, /**< The object is a thread. */
RT_Object_Class_Semaphore, /**< The object is a semaphore. */
RT_Object_Class_Mutex, /**< The object is a mutex. */
RT_Object_Class_Event, /**< The object is a event. */
RT_Object_Class_MailBox, /**< The object is a mail box. */
RT_Object_Class_MessageQueue, /**< The object is a message queue. */
RT_Object_Class_MemHeap, /**< The object is a memory heap */
RT_Object_Class_MemPool, /**< The object is a memory pool. */
RT_Object_Class_Device, /**< The object is a device */
RT_Object_Class_Timer, /**< The object is a timer. */
RT_Object_Class_Module, /**< The object is a module. */
RT_Object_Class_Unknown, /**< The object is unknown. */
RT_Object_Class_Static = 0x80 /**< The object is a static object. */
};
对象数据类型定义
在RTT中,为了方便管理这些对象,专门定义了一个对象数据类型结构,具体见下面的代码
/**
* Base structure of Kernel object
*/
struct rt_object
{
char name[RT_NAME_MAX]; (1) /**< name of kernel object */
rt_uint8_t type; (2) /**< type of kernel object */
rt_uint8_t flag; (3) /**< flag of kernel object */
#ifdef RT_USING_MODULE
void *module_id; /**< id of application module */
#endif
rt_list_t list; (4) /**< list node of kernel object */
};
typedef struct rt_object *rt_object_t; /**< Type for kernel objects. */
(1):对象名字,字符串形式,方便调试,最大长度由rt_config.h中的宏RT_NAME_MAX决定,默认长度为8.
(2):对象的类型,RT-Thread为每一个对象都打上了数字标签,取值由rt_object_class_type枚举类型限定。
(3):对象的状态
(4):对象的列表节点,每个对象都可以通过自己的列表节点list将自己挂到容器列表中,什么是容器,下文中将会进行解释。
(5):对象数据类型,RT-Thread中会为每一个新的结构体用typedef 重定义一个指针类型的数据结构。
在线程控制块中添加对象成员
在RT-Thread中,每个对象都会有对应的一个结构体,这个结构体叫做该对象的控制块,如线程会有一个线程控制块,定时器会有一个定时器控制块,信号量会有一个信号量控制块等。这些控制块的开头都会包含一个内核对象结构体,或者直接将对象结构体的成员放在对象控制块结构体的开头,其中线程控制块的开头放置的就是对象结构体的成员,如下代码所示,其余都是直接在控制块的开头直接使用struct rt_object直接定义一个内核对象变量。
线程控制块的开头,对象的结构体成员
struct rt_thread
{
/* rt object */
char name[RT_NAME_MAX]; /**< the name of thread */
rt_uint8_t type; /**< type of object */
rt_uint8_t flags; /**< thread's flags */
rt_list_t list; /**< the object list */
什么是容器
在RTT中,每当用户创建一个对象,如线程, 就会将这个对象放到一个叫做容器的地方,这样做的目的是为了方便管理,这时你可能会问,管理什么?在RT-Thread的组件finsh的使用中,就需要使用到容器,通过扫描容器的内核对象来获取各个内核对象的状态,然后输出调试信息,目前,我们只需要知道所有创建的对象都会被放到容器中即可。
那什么是容器,从代码上来看,容器就是一个数组,是一个全局变量,数据类型为struct rt_object_information,在object.c中定义,具体见下面代码所示
static struct rt_object_information rt_object_container[RT_Object_Info_Unknown] =
{
/* initialize object container - thread */
{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread)},
#ifdef RT_USING_SEMAPHORE
/* initialize object container - semaphore */
{RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore), sizeof(struct rt_semaphore)},
#endif
#ifdef RT_USING_MUTEX
/* initialize object container - mutex */
{RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Mutex), sizeof(struct rt_mutex)},
#endif
#ifdef RT_USING_EVENT
/* initialize object container - event */
{RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Event), sizeof(struct rt_event)},
#endif
#ifdef RT_USING_MAILBOX
/* initialize object container - mailbox */
{RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_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_Info_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_Info_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_Info_MemPool), sizeof(struct rt_mempool)},
#endif
#ifdef RT_USING_DEVICE
/* initialize object container - device */
{RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device)},
#endif
/* initialize object container - timer */
{RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer), sizeof(struct rt_timer)},
#ifdef RT_USING_MODULE
/* initialize object container - module */
{RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Module), sizeof(struct rt_dlmodule)},
#endif
};
对象容器是一个全局变量的数组,数据类型为struct rt_object_information,这是一个结构体类型,包含对象的三个信息,分别为对象类型,对象列表节点头和对象的大小,在rt_def.h中定义,具体实现见下面代码所示
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 */
};
(1)对象的类型,取值只能是rt_object_class_type枚举类型,具体取值见上面列出的枚举体
(2)对象列表节点头,每当对象创建的时候,对象就会通过他们控制块里面的list节点将自己挂到对象容器中同一个对象列表中,容器数组的小标就是对象的类型。
(3)对象的大小,可直接通过sizeof(对象控制块类型)获取。
容器的大小直接由RT_Object_Info_Unknown决定,RT_Object_Info_Unknown是一个枚举体类型的变量,在rt_object_info_type这个枚举体结构体里面定义,具体见下代码
enum rt_object_info_type
{
RT_Object_Info_Thread = 0, /**< The object is a thread. */
#ifdef RT_USING_SEMAPHORE
RT_Object_Info_Semaphore, /**< The object is a semaphore. */
#endif
#ifdef RT_USING_MUTEX
RT_Object_Info_Mutex, /**< The object is a mutex. */
#endif
#ifdef RT_USING_EVENT
RT_Object_Info_Event, /**< The object is a event. */
#endif
#ifdef RT_USING_MAILBOX
RT_Object_Info_MailBox, /**< The object is a mail box. */
#endif
#ifdef RT_USING_MESSAGEQUEUE
RT_Object_Info_MessageQueue, /**< The object is a message queue. */
#endif
#ifdef RT_USING_MEMHEAP
RT_Object_Info_MemHeap, /**< The object is a memory heap */
#endif
#ifdef RT_USING_MEMPOOL
RT_Object_Info_MemPool, /**< The object is a memory pool. */
#endif
#ifdef RT_USING_DEVICE
RT_Object_Info_Device, /**< The object is a device */
#endif
RT_Object_Info_Timer, /**< The object is a timer. */
#ifdef RT_USING_MODULE
RT_Object_Info_Module, /**< The object is a module. */
#endif
RT_Object_Info_Unknown, /**< The object is unknown. */
};
#define _OBJ_CONTAINER_LIST_INIT(c)
{&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}
static struct rt_object_information rt_object_container[RT_Object_Info_Unknown] =
{
/* initialize object container - thread */
{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread)},
#ifdef RT_USING_SEMAPHORE
/* initialize object container - semaphore */
{RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore), sizeof(struct rt_semaphore)},
#endif
#ifdef RT_USING_MUTEX
/* initialize object container - mutex */
{RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Mutex), sizeof(struct rt_mutex)},
#endif
#ifdef RT_USING_EVENT
/* initialize object container - event */
{RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Event), sizeof(struct rt_event)},
#endif
#ifdef RT_USING_MAILBOX
/* initialize object container - mailbox */
{RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_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_Info_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_Info_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_Info_MemPool), sizeof(struct rt_mempool)},
#endif
#ifdef RT_USING_DEVICE
/* initialize object container - device */
{RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device)},
#endif
/* initialize object container - timer */
{RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer), sizeof(struct rt_timer)},
#ifdef RT_USING_MODULE
/* initialize object container - module */
{RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Module), sizeof(struct rt_dlmodule)},
#endif
};
可以看出,RT_Object_Info_Unknown 位于枚举结构体的最后,它的具体取值由前面的成员多少决定,前面的成员是否有效都是通过宏定义来实现的,只有在rtconfig.h中定义了相应的宏,对应的枚举体成员才会有效,默认在这些宏都没有定义的情况下只有RT_Object_Info_Thread和RT_Object_Info_Timer有效,此时RT_Object_Info_Unknown的值等于2,当这些宏全部有效,此时RT_Object_Info_Unknown的值等于2,这些宏全部有效,RT_Object_Info_Unknown的值等于11,即容器的大小是12,此时是最大的,C语言知识,如果枚举体类型成员值没有具体指定,那么最后一个值是在前一个成员值的基础上加一。
初始化对象容器——线程,线程是RTT中最基本的对象,是必须存在的,它和其他对象不一样,没有通过宏来选择,接下来下面的信号量,邮箱都通过对应的宏定义来控制是否初始化,即只有在创建了相应的对象之后,才在对象容器里面初始化。
初始化对象类型为线程。
初始化对象列表节点头里面的next和prev两个节点指针分别指向自身。
容器的接口实现
获取指定类型的对象信息
从容器中,获取指定类型的对象的信息由函数rt_object_get_information()实现,具体见
struct rt_object_information *
rt_object_get_information(enum rt_object_class_type type)
{
int index;
for (index = 0; index < RT_Object_Info_Unknown; index ++)
if (rt_object_container[index].type == type) return &rt_object_container[index];
return RT_NULL;
}
容器在定义的时候,大小是固定的,由RT_Object_Info_Unknown这个枚举值决定,但容器里面的成员是否初始化就不一定了,其中线程和定时器这两个对象默认会被初始化,剩下的由其他对象的宏定义决定,rt_object_get_information() 会遍历整个容器对象,如果对象的类型等
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
struct rt_dlmodule *module = dlmodule_self();
#endif
/* get object information */
information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL);
/* 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();
#ifdef RT_USING_MODULE
if (module)
{
rt_list_insert_after(&(module->object_list), &(object->list));
object->module_id = (void *)module;
}
else
#endif
{
/* insert object into information object list */
rt_list_insert_after(&(information->object_list), &(object->list));
}
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
}
调用对象初始化函数
rt_err_t rt_thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
{
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(stack_start != RT_NULL);
/* init thread object */
rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);
最后
以上就是爱笑砖头为你收集整理的RT-Thread对象容器的实现的全部内容,希望文章能够帮你解决RT-Thread对象容器的实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复