【RT-Thread基础教程】邮箱的使用

文章目录

  • 前言
  • 一、邮箱的特性
  • 二、邮箱操作函数
  • 2.1 创建邮箱
      • 创建动态邮箱
      • 创建静态邮箱
    • 2.2 删除邮箱
    • 2.3 发邮件
      • 2.4 取邮件
  • 三、示例代码
  • 总结


前言

RT-Thread是一个开源的实时嵌入式操作系统,广泛应用于各种嵌入式系统和物联网设备。在RT-Thread中,邮箱是一种常用的线程间通信机制,用于实现不同线程之间的消息传递。本教程将介绍如何在RT-Thread中使用邮箱,以便开发者更好地利用这一功能。


一、邮箱的特性

邮箱的本质是环形缓冲区:

邮箱中的每一封邮件,只能容纳 4 字节内容(对于 32 位系统,指针大小刚好为 4 字节);

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

二、邮箱操作函数

邮箱由邮箱控制块管理,由结构体 rt_mailbox 表示。
使用邮箱的流程:创建/初始化邮箱、发送邮件、接收邮件、删除/脱离邮箱
在这里插入图片描述

2.1 创建邮箱

创建动态邮箱

我们可以使用下面这个函数创建动态邮箱:

rt_mailbox_t rt_mb_create (const char* name, rt_size_t size, rt_uint8_t flag);

参数说明:
name 邮箱名称
size 邮箱容量
flag 邮箱采用的等待方式: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO
返回值 邮箱对象的句柄:成功,返回句柄,以后使用句柄来操作邮箱,RT_NULL:失败

创建静态邮箱

我们可以使用下面这个函数创建静态邮箱:

 rt_err_t rt_mb_init(rt_mailbox_t mb,const char* name,void* msgpool,rt_size_t size,rt_uint8_t flag);

参数说明:
mb 邮箱对象的句柄
name 邮箱的名字
msgpool 缓冲区指针
size 邮箱容量
flag 邮箱采用的等待方式: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO
返回值 RT_EOK:成功

2.2 删除邮箱

我们可以使用下面这个函数删除rt_mb_create 函数创建的邮箱:

rt_err_t rt_mb_delete (rt_mailbox_t mb);

参数为邮箱的handle

我们可以使用下面这个函数删除rt_mb_init创建的邮箱:

rt_err_t rt_mb_detach(rt_mailbox_t mb);

参数为邮箱的handle

他们的返回值为RT_ERROR时,表示出错了

2.3 发邮件

  1. 我们可以使用下面这个函数来发送邮件:
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value);

参数1为邮箱的handle
参数2为要发送的值

  1. 我们可以使用下面这个函数来发送邮件,并等待一定的tick:
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,rt_ubase_t   value,rt_int32_t   timeout);

参数1为邮箱的handle
参数2为要发送的值
参数3为等待的tick

  1. 我们可以使用下面这个函数来发送紧急邮件:
rt_err_t rt_mb_urgent (rt_mailbox_t mb, rt_ubase_t value);

参数1为邮箱的handle
参数2为要发送的值

2.4 取邮件

我们可以使用下面这个函数来收邮件:

rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32_t* value, rt_int32_t timeout);

参数1为邮箱的handle
参数2为存储的地址
参数3为等待时间

三、示例代码

#include <rtthread.h>// 定义一个邮箱句柄
static rt_mailbox_t mailbox;// 定义一个线程1
static void thread1_entry(void *parameter)
{rt_uint32_t message = 123;// 发送消息到邮箱rt_mb_send(mailbox, &message, sizeof(message));// 等待一段时间,模拟其他操作rt_thread_delay(50);
}// 定义一个线程2
static void thread2_entry(void *parameter)
{rt_uint32_t message;// 从邮箱接收消息rt_mb_recv(mailbox, &message, RT_WAITING_FOREVER);// 处理接收到的消息rt_kprintf("Received message: %d\n", message);
}int mailbox_example(void)
{// 创建邮箱,设置邮箱大小为5,每个消息大小为4字节mailbox = rt_mb_create("mbox", 5, RT_IPC_FLAG_FIFO);if (mailbox == RT_NULL){rt_kprintf("Failed to create mailbox!\n");return -1;}// 创建线程1rt_thread_t thread1 = rt_thread_create("t1", thread1_entry, RT_NULL, 512, 10, 10);if (thread1 != RT_NULL){rt_thread_startup(thread1);}// 创建线程2rt_thread_t thread2 = rt_thread_create("t2", thread2_entry, RT_NULL, 512, 11, 10);if (thread2 != RT_NULL){rt_thread_startup(thread2);}// 等待线程执行完成rt_thread_mdelay(100);// 删除邮箱rt_mb_delete(mailbox);return 0;
}// 在RT-Thread的初始化中调用示例函数
INIT_APP_EXPORT(mailbox_example);

在这里插入图片描述


总结

通过本教程,我们深入了解了在RT-Thread中如何有效地使用邮箱进行线程间通信。邮箱作为一种轻量级的消息传递机制,为开发者提供了一种灵活而高效的方式来实现不同线程之间的数据传递。通过合理地利用邮箱,我们能够在嵌入式系统和物联网设备中构建更为可靠和响应的应用程序。希望本教程能够帮助开发者更好地利用RT-Thread的功能,提升嵌入式系统的开发效率和性能。

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

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

相关文章

输入一个整数,输出其最长连续因子。

输入一个整数&#xff0c;输出其最长连续因子。 例如 输入&#xff1a;60 输出&#xff1a;2 3 4 5 6 注意&#xff1a;1不算因子 输入输出格式 输入描述: 输入一个整数N&#xff0c;N<10000。 输出描述: 输出其最长连续因子&#xff0c;如果有多个最长&#xff0c;输出…

Linux UnixODBC安装配置

配置 UnixODBC 梦之上关注IP属地: 香港 0.2322020.12.09 13:23:10字数 1,202阅读 5,447 麒麟&达梦适配系列: 1.麒麟服务器上安装 DM8 2.配置 UnixODBC 3.beego-ORM 适配达梦 资源紧张的时候&#xff0c;服务器是大家共用的&#xff0c;上面部署了一堆服务。所以选用doc…

ShardingJdbc实战-分库分表

文章目录 基本配置分库分表的分片策略一、inline 行表达时分片策略algorithm-expression行表达式完整案例和配置如下 二、根据实时间日期 - 按照标准规则分库分表标准分片 - Standard完整案例和配置如下 基本配置 逻辑表 逻辑表是指&#xff1a;水平拆分的数据库或者数据表的相…

大小端问题

0. 介绍 大小端计算机存储数据而安排字节的两种顺序。 针对的是字节。 大端与我们平时书写的顺序一致。 1. 大小端的判定 不需要手动判断。 有一个头文件endian.h; 可能会有宏 __BYTE_ORDER __BIG_ENDIAN __LITTLE_ENDIAN通过库来进行判断。 手动判断 根据字节存取的顺序…

【JSON2WEB】07 Amis可视化设计器CRUD增删改查

总算到重点中的核心内容&#xff0c;CRUD也就是增删改查&#xff0c;一个设计科学合理的管理信息系统&#xff0c;95%的就是CRUD&#xff0c;达不到这个比例要重新考虑一下你的数据库设计了。 1 新增页面 Step 1 启动amis-editor Setp 2 新增页面 名称和路径随便命名&#xf…

Dynamo幕墙探究系列(一)

一直想写个系列教程&#xff0c;但是没有那么多时间整理资料&#xff0c;这次呢&#xff0c;先弄个小系列吧&#xff0c;还是和之前差不多的幕墙测试&#xff0c;我们分几节课&#xff0c;一步一步深入研究。 今天先开个小头儿&#xff0c;要弄的&#xff0c;就是下面这么个模型…

对象锁与类锁

不同锁互不影响&#xff0c;共用一个锁&#xff0c;可能会发生阻塞。 1.在修饰静态方法时&#xff0c;锁定的是当前类的 Class 对象&#xff0c;在下面的例子中就是SycTest1.class 2.当修饰非静态方法时&#xff0c;锁定的就是 this 对象&#xff0c;即当前的实例化对象 public…

【Git教程】(四)版本库 —— 存储系统,存储目录,提交对象及其命名、移动与复制~

Git教程 版本库 1️⃣ 一种简单而高效的存储系统2️⃣ 存储目录&#xff1a;Blob 与 Tree3️⃣ 相同数据只存储一次4️⃣ 压缩相似内容5️⃣ 不同文件的散列值相同6️⃣ 提交对象7️⃣ 提交历史中的对象重用8️⃣ 重命名、移动与复制&#x1f33e; 总结 事实上&#xff0c;我们…

keil MDK安装armcc V5编译器

不知道从什么时候开始&#xff0c;Keil MDK默认不支持V5的编译器了&#xff0c;里面默认只有V6的编译器&#xff0c;设置界面跟V5有很大的差异不太熟悉。最可怕的是&#xff0c;之前使用V5编译的工程&#xff0c;换成V6编译器后居然报错...虽然修改一下应该也可以正常编译&…

SQL面试题(2)

第一题 创建trade_orders表: create table `trade_orders`( `trade_id` varchar(255) NULL DEFAULT NULL, `uers_id` varchar(255), `trade_fee` int(20), `product_id` varchar(255), `time` varchar(255) )ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_…

web自动化笔记九:验证码的处理方式

一、验证码常用的处理方式 ①、说明&#xff1a;Selenium中并没有对验证码处理的方法&#xff0c;在这里我们介绍一下针对验证码的几种常用处理方式 ②、方式&#xff1a; 1&#xff09;、去掉验证码&#xff08;测试环境下采用&#xff09; …

RDD算子介绍

1. RDD算子 RDD算子也叫RDD方法&#xff0c;主要分为两大类&#xff1a;转换和行动。转换&#xff0c;即一个RDD转换为另一个RDD&#xff0c;是功能的转换与补充&#xff0c;比如map&#xff0c;flatMap。行动&#xff0c;则是触发任务的执行&#xff0c;比如collect。所谓算子…

Mac专用投屏工具AirServer 7.27 for Mac中文版2024最新图文教程

Mac专用投屏工具AirServer 7.27 for Mac中文版是一款适用于Mac的投屏工具&#xff0c;可以将Mac屏幕快速投影到其他设备上&#xff0c;如电视、投影仪、平板等。 Mac专用投屏工具AirServer 7.27 for Mac中文版具有优秀的兼容性&#xff0c;可以与各种设备配合使用。无论是iPhon…

基于springboot+vue的在线考试系统(源码+论文)

文章目录 目录 文章目录 前言 一、功能设计 二、功能页面 三、论文 前言 现在我国关于在线考试系统的发展以及专注于对无纸化考试的完善程度普遍不高&#xff0c;关于对考试的模式还大部分还停留在纸介质使用的基础上&#xff0c;这种教学模式已不能解决现在的时代所产生的考试…

【MySQL】数据库的操作

【MySQL】数据库的操作 目录 【MySQL】数据库的操作创建数据库数据库的编码集和校验集查看系统默认字符集以及校验规则查看数据库支持的字符集查看数据库支持的字符集校验规则校验规则对数据库的影响数据库的删除 数据库的备份和恢复备份还原不备份整个数据库&#xff0c;而是备…

YOLOv9改进|增加SPD-Conv无卷积步长或池化:用于低分辨率图像和小物体的新 CNN 模块

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、文章摘要 卷积神经网络(CNNs)在计算即使觉任务中如图像分类和目标检测等取得了显著的成功。然而&#xff0c;当图像分辨率较低或物体较小时&…

【LeetCode刷题】146. LRU 缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否则返回 -…

【InternLM 实战营笔记】浦语·灵笔的图文理解及创作部署、 Lagent 工具调用 Demo

浦语灵笔的图文理解及创作部署 浦语灵笔是基于书生浦语大语言模型研发的视觉-语言大模型&#xff0c;提供出色的图文理解和创作能力&#xff0c;结合了视觉和语言的先进技术&#xff0c;能够实现图像到文本、文本到图像的双向转换。使用浦语灵笔大模型可以轻松的创作一篇图文推…

进程间的通信 -- 共享内存

一 共享内存的概念 1. 1 共享内存的原理 之前我们学过管道通信&#xff0c;分为匿名管道和命名管道&#xff0c;匿名管道通过父子进程的属性继承原理来完成父子进程看到同一份资源的目的&#xff0c;而命名管道则是通过路径与文件名来唯一标识管道文件&#xff0c;来让不同的进…

typescript 的常用方式

文章目录 前言一、绑定props 默认值的方式&#xff1a;withDefaults1.vue2 的props设置默认值2.vue3 的props设置默认值(1) 不设置默认值的写法(2) 设置默认值的写法&#xff08;分离模式&#xff09;(3) 设置默认值的写法&#xff08;组合模式&#xff09; 二、定义一个二维数…