【RT-Thread】消息邮箱

RT-Thread —邮箱 学习笔记

目录

概述

邮箱的特性

创建/初始化

删除/脱离

发邮件

收邮件


概述

消息队列的本质是链表:
  • 空闲消息块链表:往队列里写入消息时,先从空闲链表中得到消息块;从 队列读出消息后,把消息块放入空闲链表
  • 消息块头部链表:消息写入消息块后,该消息块被放到尾部;从队列里读 消息时,从头部读。
使用消息队列可以传递各类大小的消息,它使用 memcpy 的方式写入消息、读出消息。
如果我们只是传递很小的数据,比如一些数值,可以使用邮箱:它的效率更高。

邮箱的特性

邮箱的本质是环形缓冲区:

  • 邮箱中的每一封邮件,只能容纳 4 字节内容(对于 32 位系统,指针大小刚好为 4 字节);
  • 邮件的发送通常是非阻塞的,线程、中断都可以发送邮件;也可使用阻塞方式发送;
  • 邮件的接收通常是阻塞的,取决于邮箱中是否有邮件;
  • 当一个线程向邮箱发送邮件时:
  1. 如果邮箱没满,就把数值写入邮箱中
  2. 如果邮箱满了:

        a.发送线程可以直接返回-RT_EFULL

        b.也可以挂起一段时间,在挂起的期间,别的线程或中断服务程序读了邮箱,会唤醒挂起的线程。

  • 当一个线程从邮箱接收邮件时:
  1. 如果邮箱不为空,就读取邮箱中的数值
  2. 如果邮箱为空:
        a.接收线可以直接返回-RT_ETIMOUT
        b.也可以挂起一段时间,在挂起的期间,别的线程或中断服务程序写了邮箱,会唤醒挂起的线程。
邮箱操作函数

创建/初始化

邮箱的创建有两种方法:
  • 动态分配内存:rt_mb_create() ,邮箱的内存在函数内部动态分配,分配的内存大小为邮件大小乘以邮箱容量
  • 静态分配内存:rt_mb_init(),邮箱的内存事先分配好,比如可以是数组。
rt_mb_create() 函数原型如下:
rt_mailbox_t rt_mb_create (const char* name, rt_size_t size, rt_uint8_t flag);
参数
说明
name
邮箱名称
size
邮箱容量
flag
邮箱采用的等待方式: RT_IPC_FLAG_FIFO RT_IPC_FLAG_PRIO
返回值
邮箱对象的句柄:成功,返回句柄,以后使用句柄来操作邮箱 RT_NULL :失败
rt_mb_init() 函数原型如下:
rt_err_t rt_mb_init(rt_mailbox_t mb, const char* name,
                     void* msgpool,rt_size_t size,t_uint8_t flag)
参数
说明
mb
邮箱对象的句柄
name
邮箱的名字
msgpool
缓冲区指针
size
邮箱容量
flag
邮箱采用的等待方式: RT_IPC_FLAG_FIFO RT_IPC_FLAG_PRIO
返回值
RT_EOK :成功

删除/脱离

不再使用一个邮箱时:
  • 删除它:rt_mb_delete(),只能删除使用 rt_mb_create()创建的邮箱
  • 脱离它:rt_mb_detach(),只能脱离使用 rt_mb_init()初始化的邮箱
删除邮箱的函数为 rt_mb_delete() ,它会释放内存。原型如下:
rt_err_t rt_mb_delete (rt_mailbox_t mb);
删除邮箱时,如果有线程在等待该邮箱,则内核先唤醒这些线程(线程返回值是 -
RT_ERROR ),然后再释放邮箱使用的内存,最后删除邮箱对象。
脱离邮箱将使邮箱对象被从内核对象管理器中脱离。原型如下:
rt_err_t rt_mb_detach(rt_mailbox_t mb);
脱离消息邮箱时,如果有线程在等待该邮箱,则内核会先唤醒这些线程(线程返回值
- RT_ERROR )。

发邮件

RT-Thread 有三个发送邮件的函数:
  • rt_mb_send() 发送邮件
  • rt_mb_send_wait() 等待方式发送邮件
  • rt_mb_urgent() 发送紧急邮件
线程或者中断服务程序都可以通过往邮箱里写入邮件。
发送的邮件,可以是 32 位的任意格式数据,可以是一个整型值或者一个指向某块内
存的指针。
使用 rt_mq_send() 发送消息时,只有在邮箱有可用的空闲空间时,才能成功发送消息, 否则返回错误码(-RT_EFULL)
使用 rt_mq_send_wait() 发送消息时,如果邮箱没有可用的空闲空间,会根据 timeout参数等待,超时后才返回错误。
使用 rt_mq_urgent() 发送消息时,只有在邮箱有可用的空闲空间,它才会把邮件插在邮件队首,以便这个邮件能被第 1 时间读取。
发送邮件的函数原型如下:
rt_err_t rt_mb_send (rt_mailbox_t mb, rt_uint32_t value)
参数
说明
mb
邮箱对象的句柄
value
邮件内容
返回值
RT_EOK :发送成功
RT_EFULL :邮箱满了

等待方式发送邮件的函数原型如下:
rt_err_t rt_mb_send_wait (rt_mailbox_t mb,rt_uint32_t value,rt_int32_t timeout);
参数
说明
mb 
邮箱对象的句柄
value
邮件内容
timeout
超时时间
返回值
RT_EOK :发送成功
RT_ETIMEOUT :发送超时
RT_ERROR :发送失败
发送紧急邮件的函数原型如下:
rt_err_t rt_mb_urgent (rt_mailbox_t mb, rt_ubase_t value);
参数说明
mb
邮箱对象的句柄
value
邮件内容
返回值
RT_EOK :发送成功
RT_EFULL :邮箱满了

收邮件

当邮箱有邮件时,使用收邮件函数,可以从邮箱接收邮件。
如果没有邮件,根据指定的 timeout 参数等待,直到超时结束。
函数原型如下:
rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32_t* value, rt_int32_t timeout);
参数
说明
mb
邮箱对象的句柄
value
邮件内容
timeout
超时时间
返回值
RT_EOK :接收成功
RT_ETIMEOUT :接收超时
RT_ERROR :失败,返回错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶舞澎湃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值