RT-Thread学习笔记——邮箱

本文详细介绍了RT-Thread操作系统中的邮箱机制,包括其工作原理、相关函数,以及基于STM32的邮箱使用示例。通过创建邮箱、发送和接收邮件,展示了如何在不同线程间传递4字节信息。此外,还探讨了邮箱在实际项目中的应用场合和技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

前面讲了RT-Thread的信号量、互斥量以及事件集这些都是线程间的同步方式。在我们进行实际的项目开发的时候,经常会涉及到一个线程更新某个全局变量值,然后另外一个线程去读取这个全局变量值,根据这个全局变量值的不同而去执行不同的操作,在RT-Thread 中则提供了更多的工具帮助在不同的线程中间传递信息,包括邮箱、消息队列、信号用于线程间的通信方式。本文将RT-Thread的邮箱服务,包括邮箱工作机制、工作管理方式以及应用示例,基于潘多拉开发板进行实验,单片机为STM32L475VET6。

一、邮箱的工作机制

RT-Thread 操作系统的邮箱用于线程间通信,特点是开销比较低,效率较高。邮箱中的每一封邮件只能容纳固定的 4 字节内容(针对 32 位处理系统,指针的大小即为 4 个字节,所以一封邮件恰好能够容纳一个指针)。典型的邮箱也称作交换消息,如下图所示,线程或中断服务例程把一封 4 字节长度的邮件发送到邮箱中,而一个或多个线程可以从邮箱中接收这些邮件并进行处理。 

邮箱工作示意图(来源RT-Thread编程指南)
邮箱工作示意图(来源RT-Thread编程指南)

 

 (1)非阻塞方式的邮件发送过程能够安全的应用于中断服务中,是线程、中断服务、定时器向线程发送消息的有效手段。通常来说,邮件收取过程可能是阻塞的,这取决于邮箱中是否有邮件,以及收取邮件时设置的超时时间。当邮箱中不存在邮件且超时时间不为 0 时,邮件收取过程将变成阻塞方式。在这类情况下,只能由线程进行邮件的收取。

(2)当一个线程向邮箱发送邮件时,如果邮箱没满,将把邮件复制到邮箱中。如果邮箱已经满了,发送线程可以设置超时时间,选择等待挂起或直接返回  RT_EFULL。如果发送线程选择挂起等待,那么当邮箱中的邮件被收取而空出空间来时,等待挂起的发送线程将被唤醒继续发送。

(3)当一个线程从邮箱中接收邮件时,如果邮箱是空的,接收线程可以选择是否等待挂起直到收到新的邮件而唤醒,或可以设置超时时间。当达到设置的超时时间,邮箱依然未收到邮件时,这个选择超时等待的线程将被唤醒并返回 RT_ETIMEOUT。如果邮箱中存在邮件,那么接收线程将复制邮箱中的 4 个字节邮件到接收缓存中。

 

二、邮箱的相关函数

1、创建动态邮箱函数:创建邮箱对象时会先从对象管理器中分配一个邮箱对象,然后给邮箱动态分配一块内存空间用来存放邮件,这块内存的大小等于邮件大小(4 字节)与邮箱容量的乘积,接着初始化接收邮件数目和发送邮件在邮箱中的偏移量,动态创建一个邮箱对象可以调用如下的函数接口:

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

(1)入口参数:

 name:邮箱名称。
 size:邮箱容量。
 flag:邮箱标志,它可以取如下数值:RT_IPC_FLAG_FIFO 或RT_IPC_FLAG_PRIO。

(2)返回值:

 RT_NULL:创建失败。
 邮箱对象的句柄:创建成功。

 

2、删除动态邮箱函数:当用 rt_mb_create() 创建的邮箱不再被使用时,应该删除它来释放相应的系统资源,一旦操作完成,邮箱将被永久性的删除。删除邮箱时,如果有线程被挂起在该邮箱对象上,内核先唤醒挂起在该邮箱上的所有线程(

好的,我来为您介绍一下如何使用STM32L475和RT-Thread潘多拉开发板,通过按键控制LED灯和蜂鸣器的示例。 这个项目主要涉及以下几个部分: 1. 硬件连接: - 将LED灯连接到GPIO输出引脚 - 将蜂鸣器连接到另一个GPIO输出引脚 - 将按键连接到GPIO输入引脚,并配置上拉电阻 2. 软件实现: - 初始化GPIO引脚 - 配置按键中断 - 在中断服务程序中切换LED和蜂鸣器的状态 下面是一个简单的代码示例: ```c #include <rtthread.h> #include <rtdevice.h> #define LED_PIN "PA5" // LED连接的引脚 #define BUZZER_PIN "PA6" // 蜂鸣器连接的引脚 #define BUTTON_PIN "PC13" // 按键连接的引脚 static rt_bool_t led_state = RT_FALSE; static rt_bool_t buzzer_state = RT_FALSE; static void button_isr(int pin, void *args) { // 切换LED状态 led_state = !led_state; rt_pin_write(LED_PIN, led_state ? PIN_HIGH : PIN_LOW); // 切换蜂鸣器状态 buzzer_state = !buzzer_state; rt_pin_write(BUZZER_PIN, buzzer_state ? PIN_HIGH : PIN_LOW); } int btn_control_example(int argc, char **argv) { // 初始化LED引脚 rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); rt_pin_write(LED_PIN, PIN_LOW); // 初始化蜂鸣器引脚 rt_pin_mode(BUZZER_PIN, PIN_MODE_OUTPUT); rt_pin_write(BUZZER_PIN, PIN_LOW); // 初始化按键引脚 rt_pin_mode(BUTTON_PIN, PIN_MODE_INPUT_PULLUP); // 设置按键中断 rt_pin_attach_irq(BUTTON_PIN, PIN_IRQ_MODE_FALLING, button_isr, RT_NULL); rt_pin_irq_enable(BUTTON_PIN); return 0; } MSH_CMD_EXPORT(btn_control_example, Button control LED and buzzer example); ``` 这段代码实现了以下功能: 1. 初始化LED和蜂鸣器引脚为输出模式,并将其设置为低电平(关闭状态) 2. 初始化按键引脚为输入模式,并启用上拉电阻 3. 设置按键中断,当按键被按下时触发button_isr函数 4. 在button_isr函数中,切换LED和蜂鸣器的状态 要运行这个示例,你需要: 1. 将LED和蜂鸣器正确连接到指定的GPIO引脚 2. 将按键连接到PC13引脚(STM32L475的默认按键引脚) 3. 将这段代码添加到你的RT-Thread工程中 4. 在shell中输入"btn_control_example"命令运行程序 这样,你就可以通过按键来控制LED灯和蜂鸣器的开关了。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值