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,就会有多少个 ...
随机推荐
- vue-router核心概念
vue用来实现SPA的插件 使用vue-router 1. 创建路由器: router/index.js new VueRouter({ routes: [ { // 一般路由 path: '/abo ...
- 【commons】字符串工具类——commons-lang3之StringUtils
类似工具见Hutool-StrUtil 一.起步 引入maven依赖 <!-- https://mvnrepository.com/artifact/org.apache.commons/com ...
- WPF 自定义ProgressBar滚动条样式
一.前言 滚动条一般用于加载进度,我们在看视频的时候或者在浏览网页的时候经常能看到加载进度的页面.在程序开发中,默认的进度加载样式可能跟程序风格不太一样,或者加载进度的时候需要更改一下加载的样式.这个 ...
- 北京Uber优步司机奖励政策(11月16日~11月22日)
用户组:人民优步“关羽组”(适用于11月16日-11月22日)奖励政策: 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/ ...
- angualarjs $location服务
$location服务 angular使用内置的$location服务来监听.操作url,包括以下功能: - 获取.监听.改变地址栏的URL: - 与URL实现双向数据绑定(地址栏变动.前进后退或者点 ...
- 使用Python访问HDFS
最近接触到大数据,对于Skpark和Hadoop的料及都停留在第一次听到这个名词时去搜一把看看大概介绍免得跟不上时代的层次. 在实际读了点别人的代码,又自己写了一些之后,虽然谈不上理解加深,至少对于大 ...
- 第5章 Linux网络编程基础
第5章 Linux网络编程基础 5.1 socket地址与API 一.理解字节序 主机字节序一般为小端字节序.网络字节序一般为大端字节序.当格式化的数据在两台使用了不同字节序的主机之间直接传递时,接收 ...
- JSON.parse() 与 eval()
JSON(JavaScript Object Notation)是一种轻量级的数据格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是Javascript原生格式,这意味着在ja ...
- 购物单:Excel的应用
题目描述: 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠 ...
- java poi技术读取到数据库
https://www.cnblogs.com/hongten/p/java_poi_excel.html java的poi技术读取Excel数据到MySQL 这篇blog是介绍java中的poi技术 ...