RT-Thread 线程间通信 邮箱(2)

对代码进行分析:

1、创建邮箱

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

    RT_ASSERT((flag == RT_IPC_FLAG_FIFO) || (flag == RT_IPC_FLAG_PRIO));

    RT_DEBUG_NOT_IN_INTERRUPT;

    /* allocate object */
    mb = (rt_mailbox_t)rt_object_allocate(RT_Object_Class_MailBox, name);
    if (mb == RT_NULL)
        return mb;

    /* set parent */
    mb->parent.parent.flag = flag;

    /* initialize ipc object */
    _ipc_object_init(&(mb->parent));

    /* initialize mailbox */
    mb->size     = size;
    mb->msg_pool = (rt_ubase_t *)RT_KERNEL_MALLOC(mb->size * sizeof(rt_ubase_t));
    if (mb->msg_pool == RT_NULL)
    {
        /* delete mailbox object */
        rt_object_delete(&(mb->parent.parent));

        return RT_NULL;
    }
    mb->entry      = 0;
    mb->in_offset  = 0;
    mb->out_offset = 0;

    /* initialize an additional list of sender suspend thread */
    rt_list_init(&(mb->suspend_sender_thread));

    return mb;
}

    /* initialize mailbox */
    mb->size     = size;
    mb->msg_pool = (rt_ubase_t *)RT_KERNEL_MALLOC(mb->size * sizeof(rt_ubase_t));
    if (mb->msg_pool == RT_NULL)
    {
        /* delete mailbox object */
        rt_object_delete(&(mb->parent.parent));

        return RT_NULL;
    }
    mb->entry      = 0;
    mb->in_offset  = 0;
    mb->out_offset = 0;

这几步就是根据给的邮箱内的个数,去创建一块地方,用于存放邮箱内的数据。

最后将邮箱内信息的数量,第一个信息的位置,最后一个信息的位置,设定为0.

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

 2、邮箱的删除:

rt_err_t rt_mb_detach(rt_mailbox_t mb)
rt_err_t rt_mb_delete(rt_mailbox_t mb)

3、邮箱的写入:

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

这个函数的参数是,写入的邮箱的名称,写入的值,以及如果没写进去要等待的时间,三个参数。

解析内部的代码。

当邮箱满,且不愿意等待,直接返回失败:

if (mb->entry == mb->size && timeout == 0)
    {
        rt_hw_interrupt_enable(level);
        return -RT_EFULL;
    }

如果愿意等待:

将自己从系统的readtlist移除,并将自己挂在邮箱的链表里面,

启动线程内的定时器,用来计时离设置的timeout还有多久

            /* reset the timeout of thread timer and start it */
            rt_timer_control(&(thread->thread_timer),
                             RT_TIMER_CTRL_SET_TIME,
                             &timeout);
            rt_timer_start(&(thread->thread_timer));

rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value)
rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value)

普通发送即等待时间为0

紧急,就是发送的数据放在邮箱第一个的位置。

4、邮箱的读取:

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

这个函数的参数是,要读取的邮箱的名称,读取的值存放的地址,以及如果没读到内容要等待的时间,三个参数。

解析内部的代码。

首先不愿意等待直接返回失败,

如果愿意等待:

把自己从系统readylist移除,把自己挂在邮箱的另一个链表里面,启动线程内部定时器。

注意:

邮箱写入挂在邮箱的suspend_sender_thread这个链表

邮箱读取挂在邮箱的parent.suspend_thread这个链表,两个使用的链表是不一样的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值