深入探究RTOS的IPC机制----邮箱

阅读引言: 因为将来工作需要, 最近在深入学习OS的内部机制,我把我觉得重要的、核心的东西分享出来, 希望对有需要的人有所帮助, 阅读此文需要读友有RTOS基础, 以及一些操作系统的基础知识, 学习过Linux的最佳, 特别是想RT-Thread适合Linux非常像的, 代码风格、IPC机制等等。

目录

一、RT-Thread中邮箱的特性

二、 邮箱的源码实现

1,邮箱控制块

2, 创建/初始化邮箱

3, 往邮箱中发送邮件

三、邮箱的简单使用


其实想深入的理解OS的内部工作机制, 无非就是涉及到一个问题, OS使用了那些数据结构组织和管理这些内核对象, 从而实现功能的。RTOS就两点链表和定时器

一、RT-Thread中邮箱的特性

消息队列的本质是链表:
 空闲消息块链表:往队列里写入消息时,先从空闲链表中得到消息块;从队列读出消息后,把消息块放入空闲链表
 消息块头部链表:消息写入消息块后,该消息块被放到尾部;从队列里读消息时,从头部读。


使用消息队列可以传递各类大小的消息,它使用memcpy的方式写入消息、读出消息。


如果我们只是传递很小的数据,比如一些数值,可以使用邮箱:它的效率更高。这一点就可以理解为邮箱和消息队列的区别
 

邮箱在内核中的实现使用的数据结构是一个循环缓冲区, 代码再后面展示

邮箱中的每一封邮件,只能容纳4字节内容(对于32位系统,指针大小刚好为4字节);发送邮件的源码如下, 邮箱中邮件的大小定死了。


 邮件的发送通常是非阻塞的,线程、中断都可以发送邮件;也可使用阻塞方式发送;
 邮件的接收通常是阻塞的,取决于邮箱中是否有邮件;
 当一个线程向邮箱发送邮件时, 如果邮箱没满,就把数值写入邮箱中
 如果邮箱满了, 发送线程可以直接返回-RT_EFULL, 也可以挂起一段时间,在挂起的期间,别的线程或中断服务程序读了邮箱,会唤醒挂起的线程。


 当一个线程从邮箱接收邮件时:如果邮箱不为空,就读取邮箱中的数值, 如果邮箱为空:接收线可以直接返回-RT_ETIMOUT, 也可以挂起一段时间,在挂起的期间,别的线程或中断服务程序写了邮箱,会唤醒挂起的线程。

二、 邮箱的源码实现

使用邮箱的流程:创建/初始化邮箱、发送邮件、接收邮件、删除/脱离邮箱。

1,邮箱控制块

2, 创建/初始化邮箱

#ifdef RT_USING_HEAP
/*** This function will create a mailbox object from system resource** @param name the name of mailbox* @param size the size of mailbox, 邮箱中邮件的数量, 每一封邮件4byte* @param flag the flag of mailbox, 邮箱采用的等待方式, 优先级, 等待的时间大小** @return the created mailbox, RT_NULL on error happen*/
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)   //flag为邮箱等待方式
{rt_mailbox_t mb;                            //定义一个邮箱结构体指针RT_DEBUG_NOT_IN_INTERRUPT;/* allocate object, 为邮箱这样一个内核对象分配内存空间 */mb = (rt_mailbox_t)rt_object_allocate(RT_Object_Class_MailBox, name);if (mb == RT_NULL)return mb;/* set parent */mb->parent.parent.flag = flag;            //从内核对象的基类继承过来, 初始化成员/* initialize ipc object */rt_ipc_object_init(&(mb->parent));/* initialize mailbox */mb->size     = size;/* 申请邮件的空间, 根据邮件的数量 * 固定大小(4byte) */mb->msg_pool = (rt_ubase_t *)RT_KERNEL_MALLOC(mb->size * sizeof(rt_ubase_t));  //每一封邮件大小4byteif (mb->msg_pool == RT_NULL){/* delete mailbox object */rt_object_delete(&(mb->parent.parent));return RT_NULL;}mb->entry      = 0;mb->in_offset  = 0;mb->out_offset = 0;/* initialize an additional list of sender suspend thread */rt_list_init(&(mb->suspend_sender_thread));return mb;
}
RTM_EXPORT(rt_mb_create);

前面我们说邮箱的数据结构是一个循环缓存区, 是从源码的这个位置看出来的。

  

3, 往邮箱中发送邮件

/*** This function will send a mail to mailbox object. If the mailbox is full,* current thread will be suspended until timeout.** @param mb the mailbox object* @param value the mail* @param timeout the waiting time** @return the error code*/
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,    		//往哪一个邮箱中发送邮件rt_ubase_t   value,        //邮件内容rt_int32_t   timeout)		//超时等待时间
{struct rt_thread *thread;   		//定义一个线程指针register rt_ubase_t temp;		    //unsigned long类型的变量rt_uint32_t tick_delta; 			//unsigned int类型的变量/* parameter check */RT_ASSERT(mb != RT_NULL);RT_ASSERT(rt_object_get_type(&mb->parent.parent) == RT_Object_Class_MailBox);/* initialize delta tick */tick_delta = 0;/* get current thread */thread = rt_thread_self();		//获取自己的线程控制块RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mb->parent.parent)));/* disable interrupt */temp = rt_hw_interrupt_disable();/* for non-blocking call, 邮箱中没位置 */if (mb->entry == mb->size && timeout == 0){rt_hw_interrupt_enable(temp);return -RT_EFULL;}/* mailbox is full 当邮箱中没位置时, 设置了超时时间的情况 */while (mb->entry == mb->size){/* reset error number in thread */thread->error = RT_EOK;/* no waiting, return timeout */if (timeout == 0){/* enable interrupt */rt_hw_interrupt_enable(temp);return -RT_EFULL;}RT_DEBUG_IN_THREAD_CONTEXT;/* suspend current thread */rt_ipc_list_suspend(&(mb->suspend_sender_thread),thread,mb->parent.parent.flag);/* has waiting time, start thread timer */if (timeout > 0){/* get the start tick of timer */tick_delta = rt_tick_get();RT_DEBUG_LOG(RT_DEBUG_IPC, ("mb_send_wait: start timer of thread:%s\n",thread->name));/* reset the timeout of thread timer and start it */rt_timer_control(&(thread->thread_timer),RT_TIMER_CTRL_SET_TIME,&timeout);rt_timer_start(&(thread->thread_timer));}/* enable interrupt */rt_hw_interrupt_enable(temp);/* re-schedule */rt_schedule();/* resume from suspend state */if (thread->error != RT_EOK){/* return error */return thread->error;}/* disable interrupt */temp = rt_hw_interrupt_disable();/* if it's not waiting forever and then re-calculate timeout tick */if (timeout > 0){tick_delta = rt_tick_get() - tick_delta;timeout -= tick_delta;if (timeout < 0)timeout = 0;}}/* set ptr */mb->msg_pool[mb->in_offset] = value;/* increase input offset */++ mb->in_offset;if (mb->in_offset >= mb->size)mb->in_offset = 0;if(mb->entry < RT_MB_ENTRY_MAX){/* increase message entry */mb->entry ++;}else{rt_hw_interrupt_enable(temp); /* enable interrupt */return -RT_EFULL; /* value overflowed */}/* resume suspended thread */if (!rt_list_isempty(&mb->parent.suspend_thread)){rt_ipc_list_resume(&(mb->parent.suspend_thread));/* enable interrupt */rt_hw_interrupt_enable(temp);rt_schedule();return RT_EOK;}/* enable interrupt */rt_hw_interrupt_enable(temp);return RT_EOK;
}
RTM_EXPORT(rt_mb_send_wait);

三、邮箱的简单使用

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

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

相关文章

行列式和矩阵的区别

目录 一、行列式 1. 行列式的定义 2. (全)排列 3. 逆序数 二、矩阵 1. 矩阵的定义 三、行列式和矩阵的区别 四、参考书目 一、行列式 1. 行列式的定义 2. (全)排列 3. 逆序数 二、矩阵 1. 矩阵的定义 三、行列式和矩阵的区别 四、参考书目 同济大学数学系. 工程数学…

Dynamics 365 on-premise 隐藏高级查找导出按钮

提示 着急可以直接看结果代码部分 背景 Dynamics 365 on-premise中有个高级查找的功能,查询的结果支持导出,如下图 业务反馈这个有数据安全风险,要修改显示规则。 一开始想着能用RibbonWorkbench改,就很爽快得答应了业务。结果用RibbonWorkbench改不了。 反复尝试 既…

Linux远程管理日志

实验介绍 本实验旨在实现主机将日志远程发送到堡垒机或远程服务器上&#xff0c;实现通过一台机器管理整个网络内的主机的效果。 准备两台虚拟机作为生产主机和管理机&#xff0c;保证网络通畅&#xff0c;展示如下&#xff1a; 关闭firewalld&#xff0c;通过配置rsyslog&a…

Sklearn之朴素贝叶斯应用

目录 sklearn中的贝叶斯分类器 前言 1 分类器介绍 2 高斯朴素贝叶斯GaussianNB 2.1 认识高斯朴素贝叶斯 2.2 高斯朴素贝叶斯建模案例 2.3 高斯朴素贝叶斯擅长的数据集 2.3.1 三种数据集介绍 2.3.2 构建三种数据 2.3.3 数据标准化 2.3.4 朴素贝叶斯处理数据 2.4 高斯…

Treeselect是介绍及使用(梳理了我使用这个组件遇到的大部分问题)

介绍&#xff1a; Treeselect是一款基于Vue.js的树形选择器组件&#xff0c;可以快速地实现树形结构的选择功能。 这里梳理了我使用这个组件遇到的大部分问题 安装依赖&#xff1a; 首先&#xff0c;你需要在你的项目中安装Treeselect的依赖。这通常可以通过npm或yarn等来完…

基于STM32和人工智能的智能农业监测系统

目录 引言环境准备智能农业监测系统基础代码实现&#xff1a;实现智能农业监测系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统4.4 用户界面与数据可视化应用场景&#xff1a;智能农业管理与优化问题解决方案与优化收尾与总结 1. 引言 智能农业监测系统通过结合STM32嵌…

Linux - 输入输出

一、输出格式 echo //末尾自带换行 -n //取消自带换行 -e //支持转移符 常见转义符 \n换行 \t制表符 printf // 格式化输出字符串 %-10s // %s代表字符串 -10 左对齐容纳10个字符 二、输入输出重定向 file descriptors &#x…

Python | Leetcode Python题解之第155题最小栈

题目&#xff1a; 题解&#xff1a; class MinStack:def __init__(self):self.stack []self.min_stack [math.inf]def push(self, x: int) -> None:self.stack.append(x)self.min_stack.append(min(x, self.min_stack[-1]))def pop(self) -> None:self.stack.pop()sel…

AD域离线破解新思路:Trustroasting和TimeRoasting

简介 近期Tom Tervoort发表了白皮书《TIMEROASTING, TRUSTROASTING AND COMPUTER SPRAYING》并在Github发布了名为Timeroast的工具包&#xff0c;其中介绍了几种新的攻击思路TimeRoasting、Trustroasting和计算机账户密码喷洒&#xff0c;本篇文章主要对TimeRoasting和Trustro…

从零开始:使用ChatGPT快速创作引人入胜的博客内容

随着科技的飞速发展&#xff0c;人工智能逐渐渗透到我们生活的各个领域。无论是商业、教育还是娱乐&#xff0c;AI技术都在以惊人的速度改变着我们。特别是在内容创作领域&#xff0c;人工智能正发挥着越来越重要的作用。今天&#xff0c;我将和大家分享如何从零开始&#xff0…

无约束动态矩阵控制(DMC)

0、前言 动态矩阵控制&#xff08;Dynamic Matrix Control&#xff0c;DMC&#xff09;是一种典型的模型预测控制方法&#xff0c;其不需要被控对象的数学模型&#xff0c;只需要获取被控对象的阶跃响应序列即可实现控制效果&#xff0c;但其需要被控对象是渐近稳定的。 1、稳…

SVN学习(002 svn冲突解决)

尚硅谷SVN高级教程(svn操作详解) 总时长 4:53:00 共72P 此文章包含第20p-第p29的内容 冲突 产生冲突的操作 &#xff08;第一种 相互不影响的操作&#xff09; 用户1修改第二行 用户2修改第四行 用户1提交 用户2提交&#xff0c;提交的时候会提示版本已过时 这时将用…

Hadoop 2.0 大家族(一)

目录 一、Hadoop 2.0大家族概述&#xff08;一&#xff09;分布式组件&#xff08;二&#xff09;部署概述 二、ZooKeeper&#xff08;一&#xff09;ZooKeeper简介&#xff08;二&#xff09;ZooKeeper 入门 一、Hadoop 2.0大家族概述 &#xff08;一&#xff09;分布式组件 …

不懂索引,简历上都不敢写自己熟悉SQL优化

大家好&#xff0c;我是考哥。 今天给大家带来MySQL索引相关核心知识。对MySQL索引的理解甚至比你掌握SQL优化还重要&#xff0c;索引是优化SQL的前提和基础&#xff0c;我们一步步来先打好地基。 当MySQL表数据量不大时&#xff0c;缺少索引对查询性能的影响不会太大&#x…

用电子表单替代纸质表格,签到报名、出入登记更轻松

用纸质表格收集信息时&#xff0c;常常会出现数据丢失、不易统计等问题。我们可以搭建电子表单来代替线下纸质表格&#xff0c;进行信息收集、记录数据。 这些数据会保存在账号下&#xff0c;可以导出Excel或PDF进行存档&#xff1b;也可以根据企业要求自定义PDF导出格式。 并…

Linux 6.10也引进了蓝屏机制

众所周知&#xff0c;win死机后会有个蓝屏死机的故障提示页面&#xff0c;Linux 6.10 开始也将引入这个机制。 Linux 6.10 引入了一个新的 DRM Panic 处理程序基础设施&#xff0c;以便于在致命错误&#xff08;Panic&#xff09;发生时显示相关信息。 Linux 6.10 还在开发之…

【产品面对面】deepin V23 RC 新体验,文件管理器全面升级!

内容来源&#xff1a;deepin&#xff08;深度&#xff09;社区 在日复一日的数据海洋遨游中&#xff0c;是否曾因文件杂乱无章而苦恼&#xff1f;是否渴望过有一种魔法&#xff0c;能让文件瞬间归位&#xff0c;触手可及&#xff1f; 今天&#xff0c;我们带着全新的文件管理工…

【Pandas驯化-10】一文搞懂Pandas中一列混合多种数据类型to_numeric、select_dtypes处理

【Pandas驯化-10】一文搞懂Pandas中一列混合多种数据类型to_numeric、select_dtypes处理 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; …

中文分词词云图

目录 一、分词1、分词方式方法2、分词优缺点 二、jieba使用示例1、引入库2、切分模式3、加载自定义字典 三、词的可视化1、读取数据2、数据处理3、统计词频4、去除停用词5、词云图1、pyecharts绘图2、WordCloud绘图 一、分词 1、分词方式方法 以构词规则为出发点的规则分词 全…

# 消息中间件 RocketMQ 高级功能和源码分析(七)

消息中间件 RocketMQ 高级功能和源码分析&#xff08;七&#xff09; 一、 消息中间件 RocketMQ 源码分析&#xff1a;消息存储核心类介绍 1、消息存储在 store 模块中。消息存储核心类 DefaultMessageStore.java 2、消息存储核心类介绍 private final MessageStoreConfig me…