RT_Thread_进程间通讯——邮箱

1、邮箱

邮箱是线程间通信的一种方法,可以传递数据

每封邮件4个字节大小(32 位CPU,指针的大小为 4 个字节,所以一封邮件恰好能够容纳一个指针)。

struct rt_mailbox
{
    struct rt_ipc_object parent;

    rt_uint32_t* msg_pool;                /* 邮箱缓冲区的开始地址 */
    rt_uint16_t size;                     /* 邮箱缓冲区的大小     */

    rt_uint16_t entry;                    /* 邮箱中邮件的数目     */
    rt_uint16_t in_offset, out_offset;    /* 邮箱缓冲的进出指针   */
    rt_list_t suspend_sender_thread;      /* 发送线程的挂起等待队列 */
};
typedef struct rt_mailbox* rt_mailbox_t;

2、邮箱API

2.1、创建和删除邮箱

  • 静态邮箱
  rt_err_t rt_mb_init(rt_mailbox_t mb,
                    const char* name,
                    void* msgpool,
                    rt_size_t size,
                    rt_uint8_t flag)
mb邮箱对象的句柄
name邮箱名称
msgpool缓冲区指针
size邮箱容量
flag

邮箱标志,它可以取如下数值: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO,

建议采用 RT_IPC_FLAG_PRIO,即确保线程的实时性。

返回——
RT_EOK成功
rt_err_t rt_mb_detach(rt_mailbox_t mb);
参数描述
mb邮箱对象的句柄
返回——
RT_EOK成功
  • 动态邮箱
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_IPC_FLAG_PRIO,即确保线程的实时性。

返回——
RT_NULL创建失败
邮箱对象的句柄创建成功
rt_err_t rt_mb_delete (rt_mailbox_t mb);
参数描述
mb邮箱对象的句柄
返回——
RT_EOK成功

2.2、发送邮件

  • 无等待发送邮件

无等待方式发送邮件,如果邮箱满了直接返回,不会造成阻塞

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邮箱已满

2.3、接收邮件

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失败,返回错误

3、官方例程

#include <rtthread.h>

#define THREAD_PRIORITY      10
#define THREAD_TIMESLICE     5

/* 邮箱控制块 */
static struct rt_mailbox mb;
/* 用于放邮件的内存池 */
static char mb_pool[128];

static char mb_str1[] = "I'm a mail!";
static char mb_str2[] = "this is another mail!";
static char mb_str3[] = "over";

ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;

/* 线程 1 入口 */
static void thread1_entry(void *parameter)
{
    char *str;

    while (1)
    {
        rt_kprintf("thread1: try to recv a mail\n");

        /* 从邮箱中收取邮件 */
        if (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK)
        {
            rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);
            if (str == mb_str3)
                break;

            /* 延时 100ms */
            rt_thread_mdelay(100);
        }
    }
    /* 执行邮箱对象脱离 */
    rt_mb_detach(&mb);
}

ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;

/* 线程 2 入口 */
static void thread2_entry(void *parameter)
{
    rt_uint8_t count;

    count = 0;
    while (count < 10){
        count ++;
        if (count & 0x1){
            /* 发送 mb_str1 地址到邮箱中 */
            rt_mb_send(&mb, (rt_uint32_t)&mb_str1);
        }else{
            /* 发送 mb_str2 地址到邮箱中 */
            rt_mb_send(&mb, (rt_uint32_t)&mb_str2);
        }

        /* 延时 200ms */
        rt_thread_mdelay(200);
    }

    /* 发送邮件告诉线程 1,线程 2 已经运行结束 */
    rt_mb_send(&mb, (rt_uint32_t)&mb_str3);
}

int mailbox_sample(void)
{
    rt_err_t result;

    /* 初始化一个 mailbox */
    result = rt_mb_init(&mb,
                        "mbt",                      /* 名称是 mbt */
                        &mb_pool[0],                /* 邮箱用到的内存池是 mb_pool */
                        sizeof(mb_pool) / 4,        /* 邮箱中的邮件数目,因为一封邮件占 4 字节 */
                        RT_IPC_FLAG_FIFO);          /* 采用 FIFO 方式进行线程等待 */
    if (result != RT_EOK){
        rt_kprintf("init mailbox failed.\n");
        return -1;
    }

    rt_thread_init(&thread1,"thread1",thread1_entry,RT_NULL,
                   &thread1_stack[0],sizeof(thread1_stack),THREAD_PRIORITY, THREAD_TIMESLICE);
    rt_thread_startup(&thread1);

    rt_thread_init(&thread2,"thread2",thread2_entry,RT_NULL,
                   &thread2_stack[0],sizeof(thread2_stack),THREAD_PRIORITY, THREAD_TIMESLICE);
    rt_thread_startup(&thread2);
    return 0;
}

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(mailbox_sample, mailbox sample);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我并没有MSP432平台的硬件和相应的实验环境,无法为您提供具体的数据。但是,我可以为您提供一些这四种嵌入式操作系统的特点和优缺点,您可以根据您的具体应用场景选择适合的操作系统。 FreeRTOS: - 特点:开源免费,具有丰富的API和可移植性,支持多种处理器架构,支持多任务、软件定时器、信号量、队列、事件标志等功能。 - 优点:内存占用小,可靠性高,适用于资源受限的系统。 - 缺点:对于复杂的应用程序,需要开发人员编写大量的驱动程序代码。 μC/OS-II: - 特点:商业软件,具有丰富的API和可移植性,支持多种处理器架构,支持多任务、软件定时器、信号量、队列、事件标志等功能。 - 优点:可靠性高,支持实时系统,适用于复杂的应用程序。 - 缺点:价格较高,内存占用较大。 RT-Thread: - 特点:开源免费,具有丰富的API和可移植性,支持多种处理器架构,支持多任务、软件定时器、信号量、队列、事件标志等功能,支持文件系统、网络等。 - 优点:内存占用小,可靠性高,支持实时系统,具有完整的开发平台。 - 缺点:相对于商业软件,技术支持相对较少。 TI-RTOS: - 特点:商业软件,具有丰富的API和可移植性,支持多种处理器架构,支持多任务、软件定时器、信号量、队列、事件标志等功能。 - 优点:支持实时系统,具有完整的开发平台,提供了大量的驱动程序和组件。 - 缺点:价格较高,内存占用较大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值