邮箱(Mailbox)是RT-Thread中高效的线程间通信机制,其核心特点是:
- 传输固定尺寸数据:每条消息为4字节(32位系统),可传递整型或指针
- 轻量级通信:比消息队列更节省内存,适用于小数据量场景
- 优先级传递:支持紧急消息优先处理
典型应用场景: 在硬件中断服务中,通过rt_mb_send
快速传递传感器状态字,消费线程解析后触发相应动作,避免中断长时间占用CPU资源。
一、邮箱API函数
1、邮箱的创建
1
| rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
|
1 2 3 4 5
| 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位的任意格式数据,可以是一个整型值或者一个指向某块内存的指针
- 直接发送邮件:只有在邮箱有可用的空闲空间时,才能成功发送消息,否则返回错误。
1
| rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value)
|
- 等待发送邮件:如果邮箱没有可用的空闲空间,会根据timeout参数等待,超时后才返回错误。
1 2 3
| rt_err_t rt_mb_send_wait(rt_mailbox_t mb, rt_ubase_t value, rt_int32_t timeout)
|
- 紧急发送邮件:只有在邮箱有可用的空闲空间,它才会把邮件插在邮件队首,以便这个邮件能被第1时间读取。
1
| rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value)
|
3、消息的接收
当邮箱有邮件时,使用收邮件函数,可以从邮箱接收邮件。如果没有邮件,根据指定的timeout参数等待,直到超时结束。
1
| rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout)
|
4、邮箱的脱离/删除
删除或者脱离邮箱时,如果有线程在等待该邮箱,则内核先唤醒这些线程(线程返回值是RT_ERROR),然后再释放邮箱使用的内存,最后删除邮箱对象。
1
| rt_err_t rt_mb_delete(rt_mailbox_t mb)
|
1
| rt_err_t rt_mb_detach(rt_mailbox_t mb)
|
二、创建邮箱示例
1、创建邮箱
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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、接收与发送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include "thread_task.h" #include "main.h" #include <stdio.h> #include "rtthread.h" #include <rthw.h>
#define THREAD_1_PRIORITY 4 #define THREAD_1_STACK_SIZE 512 #define THREAD_1_TIMESLICE 10 static struct rt_thread *thread_1_handle;
#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;
void thread_1_entry(void* param) { uint32_t value = 0; while(1) { rt_thread_delay(4000);
rt_mb_recv(mb_dynamic, &value, 0xffffffff); HAL_GPIO_TogglePin(GPIOC, LED1_Pin); } }
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); } }
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)邮箱填满阶段
(3)恢复同步阶段