找回密码
 立即注册
搜索
查看: 1202|回复: 0

RT-Thread 邮箱与消息队列

[复制链接]

267

主题

0

回帖

1154

积分

管理员

积分
1154
发表于 2023-12-25 23:56:59 | 显示全部楼层 |阅读模式

邮箱

RT-Thread 操作系统的邮箱用于线程间通信,特点是开销比较低,效率较高。邮箱中的每一封邮件只能容纳固定的 4 字节内容(针对 32 位处理系统,指针的大小即为 4 个字节,所以一封邮件恰好能够容纳一个指针)。典型的邮箱也称作交换消息。

邮件发送不具有加急(插队)的功能。

静态邮箱初始化

初始化前资源要静态地创建。

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

静态邮箱脱管

把静态初始化的邮箱对象从内核对象管理器中脱离。

rt_err_t rt_mb_detach(rt_mailbox_t mb)

创建邮箱

动态地创建邮箱并初始化。

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

删除邮箱

脱管邮箱并释放动态资源,与 rt_mb_create 配合使用。

rt_err_t rt_mb_delete(rt_mailbox_t mb)

发送邮件

rt_err_t rt_mb_send (rt_mailbox_t mb, rt_uint32_t value)

函数调用了rt_mb_send_wait,timeout = 0

以等待方式发送邮件

邮箱满时等待。

rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
                         rt_uint32_t  value,
                         rt_int32_t   timeout)

接收邮件

支持空等待。

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

邮箱控制

不常用。

rt_err_t rt_mb_control(rt_mailbox_t mb, rt_uint8_t cmd, void *arg)

2.1.0 版 支持的命令 RT_IPC_CMD_RESET(复位邮箱)

timeout 支持以下宏:

#define RT_WAITING_FOREVER              -1              /**< Block forever until get resource. */
#define RT_WAITING_NO                   0               /**< Non-block. */

消息队列

消息队列能够接收来自线程或中断服务例程中不固定长度的消息,并把消息缓存在自己的内存空间中。其他线程也能够从消息队列中读取相应的消息,而当消息队列是空的时候,可以挂起读取线程。当有新的消息到达时,挂起的线程将被唤醒以接收并处理消息。消息队列是一种异步的通信方式。

很遗憾的是消息队列不支持发送阻塞模式(像邮箱那样的发送等待)。

消息队列初始化

静态创建。

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_t  flag)

消息队列脱管

rt_err_t rt_mq_detach(rt_mq_t mq)

动态创建消息队列

rt_mq_t rt_mq_create(const char *name,
                     rt_size_t   msg_size,
                     rt_size_t   max_msgs,
                     rt_uint8_t  flag)

删除消息队列

rt_err_t rt_mq_delete(rt_mq_t mq)

发送消息到队列

线程或者中断服务程序都可以给消息队列发送消息。当发送消息时,消息队列对象先从空闲消息链表上取下一个空闲消息块,把线程或者中断服务程序发送的消息内容复制到消息块上,然后把该消息块挂到消息队列的尾部。当且仅当空闲消息链表上有可用的空闲消息块时,发送者才能成功发送消息;当空闲消息链表上无可用消息块,说明消息队列已满,此时,发送消息的的线程或者中断程序会收到一个错误码(-RT_EFULL)。

rt_err_t rt_mq_send(rt_mq_t mq, void *buffer, rt_size_t size)

发送紧急消息到队列

发送紧急消息的过程与发送消息几乎一样,唯一的不同是,当发送紧急消息时,从空闲消息链表上取下来的消息块不是挂到消息队列的队尾,而是挂到队首,这样,接收者就能够优先接收到紧急消息,从而及时进行消息处理。

rt_err_t rt_mq_urgent(rt_mq_t mq, void *buffer, rt_size_t size)

接收消息

当消息队列中有消息时,接收者才能接收消息,否则接收者会根据超时时间设置,或挂起在消息队列的等待线程队列上,或直接返回。

rt_err_t rt_mq_recv(rt_mq_t    mq,
                    void      *buffer,
                    rt_size_t  size,
                    rt_int32_t timeout)

消息队列控制

rt_err_t rt_mq_control(rt_mq_t mq, rt_uint8_t cmd, void *arg)

支持的命令有:RT_IPC_CMD_RESET(复位)

区别

  • 邮箱只能传4字节的值,消息队列可以传递更长的值;
  • 邮箱有发送等待功能,消息队列没有;
  • 消息队列有紧急消息功能,邮箱没有紧急邮件的功能。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|棱讯科技 ( 粤ICP备2024228160号-2|粤公网安备44030002003510号 )

GMT+8, 2024-11-21 14:58 , Processed in 0.018707 second(s), 3 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表