RT-Thread系列--对象容器

news2025/1/17 4:54:22

一、目的

RT-Thread号称小而美,那具体美在哪里呢?下面我们就来说说

首先,代码简练逻辑清晰明了;其次是框架设计。

其创新性的对象容器系统是我认为最优美的设计亮点,本篇的目的就是给大家介绍一下对象容器的设计以及这样设计所带来的优势。

二、介绍

什么是对象容器(Object Container)?

RTOS中软件实体一般都会包含:线程Thread、互斥锁Mutex、信号量Semaphore、消息队列MessageQueue、邮箱MailBox、事件组EventGroup这些常用的组件。

按照C++的术语来讲就是类,在C语言中就是各种结构体。如果我们能够将系统运行过程中的各种类型的多个对象统一管理起来,我们就可以说这样的一种软件实体就是对象容器。

在RT-Thread的设计哲学中有这些类型的对象:

/**
 *  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_Null          = 0x00,      /**< The object is not used. */
    RT_Object_Class_Thread        = 0x01,      /**< The object is a thread. */
    RT_Object_Class_Semaphore     = 0x02,      /**< The object is a semaphore. */
    RT_Object_Class_Mutex         = 0x03,      /**< The object is a mutex. */
    RT_Object_Class_Event         = 0x04,      /**< The object is a event. */
    RT_Object_Class_MailBox       = 0x05,      /**< The object is a mail box. */
    RT_Object_Class_MessageQueue  = 0x06,      /**< The object is a message queue. */
    RT_Object_Class_MemHeap       = 0x07,      /**< The object is a memory heap. */
    RT_Object_Class_MemPool       = 0x08,      /**< The object is a memory pool. */
    RT_Object_Class_Device        = 0x09,      /**< The object is a device. */
    RT_Object_Class_Timer         = 0x0a,      /**< The object is a timer. */
    RT_Object_Class_Module        = 0x0b,      /**< The object is a module. */
    RT_Object_Class_Memory        = 0x0c,      /**< The object is a memory. */
    RT_Object_Class_Unknown       = 0x0e,      /**< The object is unknown. */
    RT_Object_Class_Static        = 0x80       /**< The object is a static object. */
};

总共有这么多中对象类型,每个对象类型都有一个父类struct rt_object

/**
 * Base structure of Kernel object
 */
struct rt_object
{
    char       name[RT_NAME_MAX];                       /**< name of kernel object */
    rt_uint8_t type;                                    /**< type of kernel object */
    rt_uint8_t flag;                                    /**< flag of kernel object */

#ifdef RT_USING_MODULE
    void      *module_id;                               /**< id of application module */
#endif
    rt_list_t  list;                                    /**< list node of kernel object */
};

各字段含义:

name:对象标识符,也就是说每种类型的每个对象都可以有自己的标识符

type:对象类型,记录此对象属于某个类类型,以及是否是静态对象还是动态对象

flag:记录对象的一些标志信息

list:链表头,每个对象需要挂载在各种的类的链表上


下面我们来看一下定时器类的具体定义

/**
 * timer structure
 */
struct rt_timer
{
    struct rt_object parent;                            /**< inherit from rt_object */

    rt_list_t        row[RT_TIMER_SKIP_LIST_LEVEL];

    void (*timeout_func)(void *parameter);              /**< timeout function */
    void            *parameter;                         /**< timeout function's parameter */

    rt_tick_t        init_tick;                         /**< timer timeout tick */
    rt_tick_t        timeout_tick;                      /**< timeout tick */
};

从上面的定时器结构体定义中我们可以看到第一个字段就是struct rt_object类型的父类,通过其就可以将多个定时器统一由对象容器内的定时器类链表进行管理。

下面我们看一下对象容器的定义

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

static struct rt_object_information _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
#ifdef RT_USING_HEAP
    /* initialize object container - small memory */
    {RT_Object_Class_Memory, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Memory), sizeof(struct rt_memory)},
#endif
};

首先让我们看一下_object_container,这是一个struct rt_object_information类型的结构体数组

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 */
};

各字段含义:

type:对象类的类型

object_list:对象类的链表头

object_size:属于该对象类的每个对象的大小


通过下面的图我们可以更加清晰的理解对象容器的结构

整个系统运行过程中无论是静态创建还是动态创建的类对象都会统一由对象容易管理,这样我们在进行系统资源分析的时候就可以遍历这张表。

以上就是RT-Thread对象容器的全部内容,大家可以对照着代码再理解一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/162056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sklearn聚类之谱聚类SpectralClustering

文章目录基本原理sklearn中谱聚类的构造实战基本原理 谱聚类是一种基于图论的聚类方法&#xff0c;所谓图&#xff0c;就是将空间中的所有点连接起来&#xff0c;只要这些连接中出现了一个圈&#xff0c;就可以称之为图。如果把这些连线加上一个权重&#xff0c;就叫做加权图。…

小程序开发经验分享(6)开发流程大全

一、准备的资料 我们在开发微信小程序前,需要准备下相关资料。这个资料主要是后面进行ICP备案,微信小程序认证以及申请支付接口时需要用到。 资料如下: 营业执照【个体经营户或公司都行】银行开户许可证【个体经营户可以用法人个人银行卡】,企业网银【最好开通】。相关类…

车载以太网 - DoIP实体状态信息AliveCheck - 08

我们知道车载以太网的实体在车内一般常见的就是网关和节点,而网关和节点的状态信息对我们的以太网通信尤为重要,我们只有知道节点或者网关所处的状态,才能更好的进行下一步处理或者诊断,今天我们就来详细的了解下DoIP实体的状态信息这部分在ISO 13400中的定义。 DoIP实体状…

多图解析manacher算法原理

什么是manacher算法 用于快速计算一个字符串的最长回文子串 什么是最长回文子串&#xff1f; 例如&#xff1a;abc12321中&#xff0c;最长回文子串为12321&#xff0c;即子字符串中最长&#xff0c;且是回文的那个 怎么用暴力做法找出最长回文子串呢&#xff1f; 长度为奇…

线程等待,线程休眠,线程状态

线程等待:因为线程与线程之间&#xff0c;调度顺序是完全不确定&#xff0c;它取决于操作系统本身调度器的一个实现&#xff0c;但是有时候我们希望这个顺序是可控的&#xff0c;此时的线程等待&#xff0c;就是一种方法&#xff0c;用来控制线程结束的先后顺序&#xff1b; 1)…

神经网络基础部件-激活函数详解

本文分析了激活函数对于神经网络的必要性&#xff0c;同时讲解了几种常见的激活函数的原理&#xff0c;并给出相关公式、代码和示例图。 一&#xff0c;激活函数概述 1.1&#xff0c;前言 人工神经元(Artificial Neuron)&#xff0c;简称神经元(Neuron)&#xff0c;是构成神经…

[linux] 冯诺依曼体系及操作系统的概念

文章目录1. 冯诺依曼体系结构1. 为什么要有内存&#xff1f;1. 若内存不存在2. 若内存存在结论12.在硬件层面&#xff0c;单机和跨单机之间数据流是如何流向的&#xff1f;结论22. 操作系统(Operator System)1. 概念2.如何理解操作系统对硬件管理&#xff1f;结论13.管理者和被…

Linux安装 MySQL

1、MySQL安装方式 Linux MySQL安装有很多方式&#xff1a;yum安装、apt-get安装、rpm安装、二进制安装、源码编译安装。 比较通用的做法就是&#xff0c;二进制安装、源码编译安装&#xff0c;但是源码编译安装太麻烦&#xff0c;所以一般都是选择二进制安装。本文就是采用二…

百度百科创建词条参考资料问题汇总

百度百科词条编辑规则是相当复杂的&#xff0c;不是单纯写一写百度词条内容那么简单&#xff0c;还需要准备对应的参考资料来佐证你内容的真实性&#xff0c;很多小伙伴就因为这个参考资料犯了难&#xff0c;每次词条审核不通过的原因也大部分是因为参考资料的问题。 参考资料…

爬虫攻守道 - 2023最新 - Python Selenium 实现 - 数据去伪存真,正则表达式谁与争锋 - 爬取某天气网站历史数据

前言 前面写过3篇文章&#xff0c;分别介绍了反爬措施&#xff0c;JS逆向ajax获取数据&#xff0c;以及正则表达式匹配开头、结尾、中间的用法。第3篇算是本文 Python Selenium 爬虫实现方案的子集&#xff0c;大家可以参照阅读。 另外本意是“攻守”&#xff0c;不知道为何输…

【搞懂AUTOSAR网络管理测试】AUTOSAR网络管理规范需求解读

文章目录前言一、名词解释二、NM报文1.NM报文格式2.NM报文数据场内容三、NM状态机1.NM状态转换图2.状态前言 AUTOSAR Automotive Open System Architecture&#xff0c;汽车开放系统架构&#xff0c;由全球汽车制造商、部件供应商及其他电子、半导体和软件系统公司联合建立&am…

【Nginx】Nginx配置实例-负载均衡

1. 首先准备两个同时启动的 Tomcat2. 在 nginx.conf 中进行配置 1. 首先准备两个同时启动的 Tomcat 2. 在 nginx.conf 中进行配置 在 nginx.conf 中进行配置 随着互联网信息的爆炸性增长&#xff0c;负载均衡&#xff08;load balance&#xff09;已经不再是一个很陌生的话题…

中睿天下入选“2023年网络安全服务阳光行动”成员单位

近日&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;正式公布了“2023年网络安全服务阳光行动”成员单位名单。中睿天下作为以“实战对抗”为特点的能力价值型网络安全厂商&#xff0c;凭借领先的产品方案、专业的服务支持和优秀的行业自律精神成功入选。为规范…

12、Javaweb_登录添加删除修改多选删除分页查询复杂条件查询案例

1. 综合练习 1. 简单功能 1. 列表查询 2. 登录 3. 添加 4. 删除 5. 修改 2. 复杂功能 1. 删除选中 2. 分页查询 * 好处&#xff1a; 1. 减轻服务器内存的开销 …

C/C++数据类型转换详解

目录 C语言数据类型转换 1、自动类型转换 &#xff08;1&#xff09;算术表达式的自动类型转换 &#xff08;2&#xff09;赋值运算中的自动类型转换 2、强制类型转换 C数据类型转换 1、static_cast<> 2、const_cast<> 3、dynamic_cast<> 4、reint…

【Allegro软件PCB设计120问解析】第78问 如何在PCB中手动添加差分对及自动添加差分对属性呢?

答:设计PCB过程中,若设计中有差分对信号,则需要将是差分的2个信号设置为差分对,设置差分对有2种方式:手动添加及自动添加。 1、 手动添加差分对: 第一步,点击Setup-Constraints-Constraint Manager调出CM规则管理器,然后到Physical规则管理器下点击Net-All Layers,然…

React脚手架+组件化开发+组件生命周期+组件通信

react脚手架&#xff08;create-react-app&#xff09; 1.作用&#xff1a; 帮助我们生成一个通用的目录结构&#xff0c;并且已经将我们所需的工程环境配置好 2.依赖环境 脚手架都是使用node编写的&#xff0c;并且都是基于webpack的&#xff1b; 3.安装node 4.安装脚手架 n…

在哔站黑马程序员学习Spring—Spring Framework—(一)核心容器(core container)学习笔记

一、spring介绍 spring是一个大家族全家桶&#xff0c;spring技术是JavaEE开发必备技能。spring技术解决的问题&#xff1a;一是简化开发&#xff0c;降低企业级开发的复杂性。二是框架整合&#xff0c;高效整合其他技术&#xff0c;提高企业级应用开发与运行效率。 spring技术…

git revert和git reset的差异点和区别

git revert 定义 撤销某次提交,此次撤销操作和之前的commit记录都会保留。 git revert会根据commitid找到此次提交的变更内容&#xff0c;并撤销这些变更并作为一次新commit提交。 ps:此次commit和正常commit相同&#xff0c;也可以被revert revert和reset有本质的差别&#…

使用C#开发ChatGPT聊天程序

使用C#开发ChatGPT聊天程序 总体效果如下&#xff1a; 源码下载 关键点1&#xff1a;无边框窗口拖动 Window中设置AllowsTransparency"True"、 Background"Transparent"以及WindowStyle"None"这样设置的话默认窗口的标题栏为不可见状态&…