RT-Thread 邮箱与消息队列
## 邮箱
RT-Thread 操作系统的邮箱用于线程间通信,特点是开销比较低,效率较高。邮箱中的每一封邮件只能容纳固定的 4 字节内容(针对 32 位处理系统,指针的大小即为 4 个字节,所以一封邮件恰好能够容纳一个指针)。典型的邮箱也称作交换消息。
邮件发送不具有加急(插队)的功能。
**静态邮箱初始化**
初始化前资源要静态地创建。
```c
rt_err_t rt_mb_init(rt_mailbox_t mb,
const char*name,
void *msgpool,
rt_size_t size,
rt_uint8_t flag)
```
**静态邮箱脱管**
把静态初始化的邮箱对象从内核对象管理器中脱离。
```c
rt_err_t rt_mb_detach(rt_mailbox_t mb)
```
**创建邮箱**
动态地创建邮箱并初始化。
```c
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
```
**删除邮箱**
脱管邮箱并释放动态资源,与 `rt_mb_create` 配合使用。
```c
rt_err_t rt_mb_delete(rt_mailbox_t mb)
```
**发送邮件**
```c
rt_err_t rt_mb_send (rt_mailbox_t mb, rt_uint32_t value)
```
函数调用了rt_mb_send_wait,timeout = 0
**以等待方式发送邮件**
邮箱满时等待。
```c
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
rt_uint32_tvalue,
rt_int32_t timeout)
```
**接收邮件**
支持空等待。
```c
rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout)
```
**邮箱控制**
不常用。
```c
rt_err_t rt_mb_control(rt_mailbox_t mb, rt_uint8_t cmd, void *arg)
```
2.1.0 版 支持的命令 `RT_IPC_CMD_RESET`(复位邮箱)
timeout 支持以下宏:
```c
#define RT_WAITING_FOREVER -1 /**< Block forever until get resource. */
#define RT_WAITING_NO 0 /**< Non-block. */
```
## 消息队列
消息队列能够接收来自线程或中断服务例程中不固定长度的消息,并把消息缓存在自己的内存空间中。其他线程也能够从消息队列中读取相应的消息,而当消息队列是空的时候,可以挂起读取线程。当有新的消息到达时,挂起的线程将被唤醒以接收并处理消息。消息队列是一种异步的通信方式。
很遗憾的是消息队列不支持发送阻塞模式(像邮箱那样的发送等待)。
**消息队列初始化**
静态创建。
```c
rt_err_t rt_mq_init(rt_mq_t mq,
const char *name,
void *msgpool,
rt_size_t msg_size,
rt_size_t pool_size,
rt_uint8_tflag)
```
**消息队列脱管**
```c
rt_err_t rt_mq_detach(rt_mq_t mq)
```
**动态创建消息队列**
```c
rt_mq_t rt_mq_create(const char *name,
rt_size_t msg_size,
rt_size_t max_msgs,
rt_uint8_tflag)
```
**删除消息队列**
```c
rt_err_t rt_mq_delete(rt_mq_t mq)
```
**发送消息到队列**
线程或者中断服务程序都可以给消息队列发送消息。当发送消息时,消息队列对象先从空闲消息链表上取下一个空闲消息块,把线程或者中断服务程序发送的消息内容复制到消息块上,然后把该消息块挂到消息队列的尾部。当且仅当空闲消息链表上有可用的空闲消息块时,发送者才能成功发送消息;当空闲消息链表上无可用消息块,说明消息队列已满,此时,发送消息的的线程或者中断程序会收到一个错误码(-RT_EFULL)。
```c
rt_err_t rt_mq_send(rt_mq_t mq, void *buffer, rt_size_t size)
```
**发送紧急消息到队列**
发送紧急消息的过程与发送消息几乎一样,唯一的不同是,当发送紧急消息时,从空闲消息链表上取下来的消息块不是挂到消息队列的队尾,而是挂到队首,这样,接收者就能够优先接收到紧急消息,从而及时进行消息处理。
```c
rt_err_t rt_mq_urgent(rt_mq_t mq, void *buffer, rt_size_t size)
```
**接收消息**
当消息队列中有消息时,接收者才能接收消息,否则接收者会根据超时时间设置,或挂起在消息队列的等待线程队列上,或直接返回。
```c
rt_err_t rt_mq_recv(rt_mq_t mq,
void *buffer,
rt_size_tsize,
rt_int32_t timeout)
```
**消息队列控制**
```c
rt_err_t rt_mq_control(rt_mq_t mq, rt_uint8_t cmd, void *arg)
```
支持的命令有:RT_IPC_CMD_RESET(复位)
## 区别
- 邮箱只能传4字节的值,消息队列可以传递更长的值;
- 邮箱有发送等待功能,消息队列没有;
- 消息队列有紧急消息功能,邮箱没有紧急邮件的功能。
页:
[1]