专栏首页嵌入式大杂烩【RT-Thread笔记】内核对象模型

【RT-Thread笔记】内核对象模型

RT-Thread中的对象有哪些?

RT-Thread包括了很多不同类型的对象,如线程,信号量,互斥量等。在代码中,这些对象被汇总到一个枚举中(在rtdef.h中):

enum rt_object_class_type
{
    RT_Object_Class_Null   = 0,                         /**< 这个对象是未使用 */
    RT_Object_Class_Thread,                             /**< 对象是线程 */
    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                       /**< 对象是静态对象 */
};

在RT-Thread中,为了能很好的管理这些对象,专门定义了一个对象结构体(对象控制块),如下(在rtdef.h中):

struct rt_object
{
    char       name[RT_NAME_MAX];                       /**< 内核对象的名字 */
    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_object里的内容全搬过来了,而不是像定时器对象结构体那样定义一个rt_object类型的成员以达到继承的目的。

RT-Thread代码的层次感很强,让我们学习起来很有条理,比如信号量、互斥量、事件、邮箱、消息队列这几类对象具有共性,都是用于线程间的同步及通信(即IPC对象)。然后,RT-Thread又把这些公共的信息给抽取出来成一个新的结构体。如:

信号量对象:

IPC:Inter-ProcessCommunication,进程间通信。在RT-Thread实时操作系统中,IPC对象的作 用是进行线程间同步与通信。

C语言虽是一门面向过程的语言,但此处,我们知道在C中也可以使用面向对象的思想来设计的程序。以上这些内核对象继承关系可以用下面这张图清楚地表示:

什么是静态对象、动态对象?

RT-Thread内核采用面向对象的设计思想进行设计。其内核对象分为两类:静态内核对象和动态内核对象。

静态内核对象使用的内存空间是编译时决定的,且运行过程中是不会变化的,只有当程序退出的时候这些内存空间才会被系统回收。

动态内核对象使用的内存空间是动态分配的,即在程序运行过程中动态分配的。动态对象依赖于堆管理器,运行时申请RAM空间,当对象被删除后,占用的RAM空间被释放。关于C语言的内存的知识可查看往期笔记:

【C语言笔记】内存笔记

关于对象的创建与删除的接口在源文件object.c中,object.c有如下接口:

静态对象的创建与删除

静态对象的创建(初始化)接口:

void rt_object_init(struct rt_object         *object,  /* 对象指针 */
                    enum rt_object_class_type type,       /* 对象类型 */
                    const char               *name);   /* 对象名字 */

静态对象的删除(脱离)接口:

void rt_object_detach(rt_object_t object);

该接口的作用是把静态对象从内核管理器中脱离出来。静态对象脱离后,对象占用的内存并不会被释放。

动态对象的创建与删除

动态对象的创建(分配)接口:

rt_object_t rt_object_allocate(enum rt_object_class_type type,  /* 对象类型 */
                               const char *name);                /* 对象名字 */

返回值RT_NULL则表示分配失败,否则,分配成功的对象句柄。

动态对象的删除接口:

void rt_object_delete(rt_object_t object);

当调用以上接口时,首先从对象容器链表中脱离对象,然后释放对象所占用的内存。

RT-Thread如何管理内核对象?

RT-Thread中有那么多种内核对象,它是怎么管理这些内核对象呢?其使用对象容器来管理这些对象。这个对象容器给每一类内核对象分配一个链表,每当创建一个对象实体,这个对象实体就被链接到对应的链表上,如:

这个对象容器对应到代码中是一个struct rt_object_information类型的结构体数组rt_object_container[RT_Object_Info_Unknown]。其中RT_Object_Info_Unknown的值为对象类型的种数。RT-Thread是一个可裁剪的系统,可以通过相应宏打开/关闭对象模块,所以这个值是根据最终对象类型种类确定的。

C语言知识:如果枚举类型的成员值没有具体指定,那么后一个值是在前一个成员值的基础上加1。

struct rt_object_information的内容如下:

其中,rt_list_t是一个双链表结点结构体,该结构体如下:

结构体数组(对象容器)rt_object_container中的对象链表初始化为:

其中,_OBJ_CONTAINER_LIST_INIT是一个宏,该宏内容如下:

#define _OBJ_CONTAINER_LIST_INIT(c)     \
    {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}

初始化对象列表节点头里面的nextprev两个节点指针分别指向自身,如:

若创建两个线程对象,则对象容器里变为:

End:以上就是本次的笔记分享,如有错误,欢迎之处!

参考资料:

1、《RT-Thread编程指南》 2、[野火]《RT-Thread 内核实现与应用开发实战—基于STM32》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【工具】这么好用的代码阅读器你装了吗?

    作为一名程序员,我们不仅要多动手编代码,而且还应多阅读一些优秀的代码,如C语言的一些第三方库文件、嵌入式中Linux内核源码以及一些项目的代码等。这些源码往往都...

    正念君
  • 【C语言笔记】使用notepad++、MinGW来开发C程序

    Visual C++是Microsoft公司推出的用于开发C/C++程序的一款经典的IDE,很多高校都使用其作为教学工具来讲解C和C++。但是,Visual C...

    正念君
  • 【Linux笔记】make工程管理工具(二)

    上一篇笔记分享了使用make工具编译C程序的方法(【Linux笔记】make工程管理工具(一)),但是还未分享make工具是什么,本篇笔记就来看一下make工具...

    正念君
  • 探究卫星有关的安全问题

    大家好,好久不见甚是想念~我卫星哥又回来了。可能大家察觉到了,卫星技术渐渐开始平民化。民营航天企业暂露头角,科技企业也排队发射自己的“小卫星”。咱们暂且不管那些...

    周俊辉
  • 学习卧谈会之LeetCode(8)

    点击公众号右下角合作转载->联系我,即可加入我的个人微信,共同探讨交流,以及入交流群(记得备注入群)!

    公众号guangcity
  • Java匹马行天下之教你用学汉语式方法学编程语言

    我试着从不同的角度带新手理解编程,希望能帮助一些真正需要的朋友进行学习,后面的三篇故事新手朋友就当真正看故事了,等你学了后面的知识,你就能理解了,现在留个简单印...

    泰斗贤若如
  • UE4 Shader开发的一些东西

    http://blog.kiteandlightning.la/ue4-hlsl-shader-development-guide-notes-tips/ h...

    逍遥剑客
  • Java 8——函数式数据处理(流)

    本篇内容大部分来自《Java 8实战》 流是什么? 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时写一个实现)...

    我没有三颗心脏
  • 【实战】美数学博士研发找对象算法

    大数据文摘
  • Java 对象的初始化过程_下

    本文将继上一篇文章《Java 对象的初始化过程_上》进一步讲述Java 对象的初始化过程。

    Melody132

扫码关注云+社区

领取腾讯云代金券