对代码进行分析:
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这个链表,两个使用的链表是不一样的