RT-Thread之邮箱使用示例
邮箱(Mailbox)是RT-Thread中高效的线程间通信机制,其核心特点是:
- 传输固定尺寸数据:每条消息为4字节(32位系统),可传递整型或指针
- 轻量级通信:比消息队列更节省内存,适用于小数据量场景
- 优先级传递:支持紧急消息优先处理
典型应用场景: 在硬件中断服务中,通过rt_mb_send快速传递传感器状态字,消费线程解析后触发相应动作,避免中断长时间占用CPU资源。
一、邮箱API函数
1、邮箱的创建
- 动态创建邮箱(推荐灵活场景)
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
- 静态创建邮箱
rt_err_t rt_mb_init(rt_mailbox_t mb,
const char *name,
void *msgpool,
rt_size_t size,
rt_uint8_t flag)
2、邮箱的发送
线程或者中断服务程序都可以通过往邮箱里写入邮件。发送的邮件,可以是32位的任意格式数据,可以是一个整型值或者一个指向某块内存的指针
- 直接发送邮件:只有在邮箱有可用的空闲空间时,才能成功发送消息,否则返回错误。
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value)
- 等待发送邮件:如果邮箱没有可用的空闲空间,会根据timeout参数等待,超时后才返回错误。
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
rt_ubase_t value,
rt_int32_t timeout)
- 紧急发送邮件:只有在邮箱有可用的空闲空间,它才会把邮件插在邮件队首,以便这个邮件能被第1时间读取。
rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value)
3、消息的接收
当邮箱有邮件时,使用收邮件函数,可以从邮箱接收邮件。如果没有邮件,根据指定的timeout参数等待,直到超时结束。
rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout)
4、邮箱的脱离/删除
删除或者脱离邮箱时,如果有线程在等待该邮箱,则内核先唤醒这些线程(线程返回值是RT_ERROR),然后再释放邮箱使用的内存,最后删除邮箱对象。
- 删除使用 rt_mb_create()创建的队列
rt_err_t rt_mb_delete(rt_mailbox_t mb)
- 脱离使用 rt_mb_init()初始化的队列
rt_err_t rt_mb_detach(rt_mailbox_t mb)
二、创建邮箱示例
1、创建邮箱
struct rt_mailbox mb_static; /* 邮箱句柄 */
uint8_t msgpool[48]; /* 邮箱静态内存池 */
/* 静态创建一个邮箱 */
rt_mb_init(
&mb_static, /* 邮箱对象的句柄 */
"mb_static_test", /* 邮箱对象名称 */
msgpool, /* 内存池指向 */
sizeof(msgpool) / 4, /* 邮箱中能容纳的邮件数量,每封邮件占四字节 */
RT_IPC_FLAG_FIFO /* 如果有多个线程等待,按照先来先得到的方法分配 */
);
rt_mailbox_t mb_dynamic; /* 邮箱句柄指针 */
/* 动态创建一个邮箱 */
mb_dynamic = rt_mb_create(
"mb_dynamic_test", /* 邮箱对象名称 */
12, /* 邮箱中能容纳的邮件数量,每封邮件占四字节 */
RT_IPC_FLAG_FIFO /* 如果有多个线程等待,按照先来先得到的方法分配 */
);
2、接收与发送消息
#include "thread_task.h"
#include "main.h"
#include <stdio.h>
#include "rtthread.h"
#include <rthw.h>
/******************************************** 线程 1 ******************************************************/
#define THREAD_1_PRIORITY 4 /* 进程优先级 */
#define THREAD_1_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_1_TIMESLICE 10 /* 进程执行时间片个数 */
static struct rt_thread *thread_1_handle; /* 进程句柄 */
/******************************************** 线程 2 ******************************************************/
#define THREAD_2_PRIORITY 5 /* 进程优先级 */
#define THREAD_2_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_2_TIMESLICE 10 /* 进程执行时间片个数 */
static struct rt_thread *thread_2_handle; /* 进程句柄 */
rt_mailbox_t mb_dynamic; /* 邮箱句柄指针 */
/**
* @brief 线程1入口函数
* @param 无
* @retval 无
*/
void thread_1_entry(void* param)
{
uint32_t value = 0;
while(1)
{
rt_thread_delay(4000); /* 精准延时4000时间片 */
rt_mb_recv(mb_dynamic, &value, 0xffffffff);
HAL_GPIO_TogglePin(GPIOC, LED1_Pin);
}
}
/**
* @brief 线程2入口函数
* @param 无
* @retval 无
*/
void thread_2_entry(void* param)
{
while(1)
{
rt_mb_send_wait(mb_dynamic, (uint32_t)0x01, 0xffffffff);
HAL_GPIO_TogglePin(GPIOC, LED2_Pin);
rt_thread_delay(200);
}
}
/**
* @brief 动态创建线程任务并启动
* @param 无
* @retval 无
*/
void ThreadStart(void)
{
rt_base_t level = rt_hw_interrupt_disable();
/* 动态创建线程 */
thread_1_handle = rt_thread_create(
"thread_1", /* 线程句柄名称*/
thread_1_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
THREAD_1_STACK_SIZE, /* 线程栈大小 */
THREAD_1_PRIORITY, /* 线程优先级 */
THREAD_1_TIMESLICE /* 线程时间片大小 */
);
rt_thread_startup(thread_1_handle); /* 启动线程 */
thread_2_handle = rt_thread_create(
"thread_2", /* 线程句柄名称*/
thread_2_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
THREAD_2_STACK_SIZE, /* 线程栈大小 */
THREAD_2_PRIORITY, /* 线程优先级 */
THREAD_2_TIMESLICE /* 线程时间片大小 */
);
rt_thread_startup(thread_2_handle); /* 启动线程 */
/* 动态创建邮箱 */
mb_dynamic = rt_mb_create(
"mb_dynamic_test",
12,
RT_IPC_FLAG_FIFO
);
rt_hw_interrupt_enable(level);
}
执行流程如下:
(1)初始阶段
- 线程1立即阻塞等待消息(邮箱空)
- 线程2开始高频发送(每200 ticks发送1次)
(2)邮箱填满阶段
-
线程2发送12条消息后邮箱满 →
rt_mb_send_wait()开始阻塞 -
系统进入双阻塞状态(线程1和2均挂起)
(3)恢复同步阶段
-
线程1的rt_thread_delay(4000)到期后:
-
消费1条消息 → 释放1个邮箱槽位
-
唤醒线程2继续发送
-
-
稳定状态:每4000 ticks消费1条,线程2每200 ticks补充1条


邮箱(Mailbox)是RT-Thread中高效的线程间通信机制。
浙公网安备 33010602011771号