RT-thread内核之对象管理系统
一、数据结构
1、对象控制块:在include/rtdef.h中定义
/**
* Base structure of Kernel object
*/
struct rt_object
{
char name[RT_NAME_MAX]; /*对象名称,RT_NAME_MAX在rtconfig.h中定义 */
rt_uint8_t type; /*内核对象类型*/
rt_uint8_t flag; /*内核对象标志*/ #ifdef RT_USING_MODULE
void *module_id; /*应用模块ID */
#endif
rt_list_t list; /*内核对象链表节点 */
};
typedef struct rt_object *rt_object_t;
这里需要注意地是,上述内核对象控制块包含了一rt_list_t类型的成员list,这个是一链表节点,便于将此内核对象加入到一链表中,其结构如下定义:
struct rt_list_node
{
struct rt_list_node *next; /*指向下一节点 */
struct rt_list_node *prev; /*指向前一节点 */
};
typedef struct rt_list_node rt_list_t;
可以看出每个内核对象链表节点的结构体都包括的下一内核对象节点和前一内核对象节点
/**
* The object type can be one of the follows with specific
* macros enabled:
* - Thread
* - Semaphore
* - Mutex
* - Event
* - MailBox
* - MessageQueue
* - MemHeap
* - MemPool
* - Device
* - Timer
* - Module
* - Unknown
* - Static
*/
enum rt_object_class_type
{
RT_Object_Class_Thread = , /*线程*/
#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_MEMHEAP
RT_Object_Class_MemHeap, /*内存堆 */
#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_container[RT_Object_Class_Unknown]中,表示当前所有使用的对象类型总数*/
RT_Object_Class_Static = 0x80 /*rt-thread以此位标志判断一个内核对象是否为静态内核对象*/
};
2、内核对象容器
RTT使用内核对象容器来管理同一类型的内核对象,并将其放入同一链表中,便于访问.内核对象信息的结构如下定义:
/**
* The information of the kernel object
*/
struct rt_object_information
{
enum rt_object_class_type type; /*内核对象类型 */
rt_list_t object_list; /*内核对象链表,该链表中包含同一类型的所有内核对象节点。内核对象静态(动态)初始化与脱离(删除)时,会在该链表中增加或移除相应内核对象节点*/
rt_size_t object_size; /*内核对象所占的大小 */
};
3、内核对象管理系统
RTT中,每一类型的内核对象都会有一内核对象容器来包容,这个类型的内核对象容器实际上是用一链表,这个链表将所有相同类型的内核对象链接起来.由于每一类型都对应着有一个这样的内核对象容器来管理,那么所有内核对象容器整体就叫做内核对象管理系统.

RTT中,内核对象管理系统是用一个rt_object_information数组来实现的,在src/object.c中定义如下:
#define _OBJ_CONTAINER_LIST_INIT(c) \ //内核对象链表节点初始化,链表起始节点的前一节点和后一节点在初始化时都指向该起始节点地址
{&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)} //内核对象管理系统,这里用rt_object_information数组来实现
struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =
{
/* initialize object container - thread */ //线程对象信息
{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Thread), sizeof(struct rt_thread)},
#ifdef RT_USING_SEMAPHORE
/* initialize object container - semaphore */ //信号量对象信息
{RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Semaphore), sizeof(struct rt_semaphore)},
#endif
#ifdef RT_USING_MUTEX
/* initialize object container - mutex */ //互斥锁对象信息
{RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Mutex), sizeof(struct rt_mutex)},
#endif
#ifdef RT_USING_EVENT
/* initialize object container - event */ //事件对象信息
{RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Event), sizeof(struct rt_event)},
#endif
#ifdef RT_USING_MAILBOX
/* initialize object container - mailbox */ //邮箱对象信息
{RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_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_Class_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_Class_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_Class_MemPool), sizeof(struct rt_mempool)},
#endif
#ifdef RT_USING_DEVICE
/* initialize object container - device */ //设备驱动对象信息
{RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Device), sizeof(struct rt_device)},
#endif
/* initialize object container - timer */ //时钟对象信息
{RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Timer), sizeof(struct rt_timer)},
#ifdef RT_USING_MODULE
/* initialize object container - module */ //模块对象信息
{RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Module), sizeof(struct rt_module)},
#endif
};
二、内核对象接口(以下接口函数在src/object.c中实现)
内核对象静态初始化:
对象初始化,实现上就是把对象放入到其相应的对象容器中,即将对象插入到对象容器链表中。
void rt_object_init(struct rt_object *object, enum rt_object_class_type type,const char *name)
内核对象动态创建:
动态创建首先要在rtconfig.h中定义RT_USING_HEAP宏。使用以上接口,首先根据对象类型来获取对象信息,然后从内存堆中分配对象所需内存空间,然后对该对象进行必要的初始化,最后将其插入到它所在的对象容器链表中。
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
静态内核对象脱离:
使用该接口后,静态内核对象将从内核对象管理器中脱离,对象占用的内存不会被释放。
void rt_object_detach(rt_object_t object)
动态内核对象删除:
使用以上接口时,首先从对象容器中脱离对象,然后释放对象所占用的内存。
void rt_object_delete(rt_object_t object)
判断是否为系统静态内核对象:
rt_bool_t rt_object_is_systemobject(rt_object_t object)
通常采用rt_object_init方式挂接到内核对象管理器中的对象是系统静态内核对象。
查找内核对象:
rt_object_t rt_object_find(const char *name, rt_uint8_t type)
使用以上接口时,在对象类型所对应的对象容器中遍历寻找指定对象,然后返回该对象,如果没有找到这样的对象,则返回空。
系统内核对象初始化:
void rt_system_object_init(void)
自从0..0以后,RTT就已经没有必须再使用此接口来对内核对象初始化了,因此,此函数是空的,但在系统初始化时还会保留调用此函数
获取指定类型的内核对象信息:
struct rt_object_information *rt_object_get_information(enum rt_object_class_type type)
{
return &rt_object_container[type];
}
RTM_EXPORT(rt_object_get_information);
RT-thread内核之对象管理系统的更多相关文章
- RT Thread 通过ENV来配置SFUD,操作SPI Flash
本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...
- STM32 + RT Thread OS 学习笔记[二]
串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1. 目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...
- STM32 + RT Thread OS 串口通讯
1. 创建项目 a) 禁用Finsh和console b) 默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...
- ASP.NET内核几大对象、ASP.NET核心知识(6)--转载
这篇博文主要介绍一下几个对象. 1)HttpContext 2)HttpRequest 3)HttpResponse 4)context. Server 5)context.Session HttpC ...
- ASP.NET内核几大对象、ASP.NET核心知识(6)
描述 其实今天的博文,是一般处理程序的后续部分,理论上应该叫一般处理程序().但是觉得文章标题后面的系列名已经有个数字,再加一个2有点怪. 这篇博文主要介绍一下几个对象. )HttpContext ) ...
- (转)内核线程对象--Event事件对象
在所有的内核对象中,事件内核对象是个最基本的对象.事件能够通知一个操作已经完成. 客户机和一个服务器,它们之间需要互相进行通信例子(vs2008 ) 事件内核对象的组成 一个使用计数(与所有内核对象一 ...
- RT thread 设备驱动组件之USART设备
本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...
- Linux 内核Ksets 对象
很多情况, 一个 kset 看来象一个 kobj_type 结构的扩展; 一个 kset 是一个嵌入到相 同类型结构的 kobject 的集合. 但是, 虽然 struct kobj_type 关注的 ...
- Android 内核--Context对象
Context(在Android中翻译为场景):一个Activity就是一个Context,一个Service也是一个Context,应用程序中有多少个Activity或者Service,就会有多少个 ...
随机推荐
- java 第八章 异常处理
一.异常简介 (一)定义: 运行期间出现的错误,而不是编译时的语法错误 例如: 1.打开一个不存在的文件 2.网络连接中断 3.数学类错误 4.操作数组越界等 (二)异常的继承树 (三)异常类的体系结 ...
- 洛谷九月月赛T1 思考
很迷的一道题目,刚开始直接枚举n个1,然后去mod m ,爆0,后来发现一个神奇性质:找到递推公式An=An-1*10+1,枚举n,不断mod m,每递推一次就1的个数加一.居然可行! 听说余数具有可 ...
- AngularJS-Learning ui-router angular-transitions
https://github.com/mgechev/AngularJS-Learning https://github.com/angular-ui/ui-router https://github ...
- 北京Uber优步司机奖励政策(9月14日~9月20日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 【LG4735】最大异或和
[LG4735]最大异或和 题意 洛谷 题解 维护一个前缀异或和\(S_i\) 对于一个询问操作\(l\).\(r\).\(x\) 就是等价于求一个位置\(p\)(\(l\leq p \leq r)\ ...
- SSM-最新pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 抓取Oracle数据快照
进入到oracle安装目录下的admin(找到这个目录)开启cmd键入sqlplus system/mima@实例名>@awrrpt.sql Would you like an HTML rep ...
- hdu1527取石子游戏(威佐夫博弈)
取石子游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- Django2.1新手图文入门教程
第一个django Web Django2.1新手图文入门教程 http://www.liujiangblog.com/blog/36/
- 【MySQL解惑笔记】忘记MySQL数据库密码
破解MySQL密码 一.MySQL5.7.5之前 只要有系统root密码就可以破解: [root@host- ~]# vim /etc/my.cnf //在配置文件中加入如下内容 [mysqld] s ...