/* re-schedule */
rt_schedule();//重新调度
/* resume from suspend state */
if (thread->error != RT_EOK)//如果此时不是被接收线程唤醒,即邮箱已以可用空间了
{
/* return error */
return thread->error;
}
/* disable interrupt */
temp = rt_hw_interrupt_disable();//关中断
/* if it's not waiting forever and then re-calculate timeout tick */
if (timeout > 0)
{
tick_delta = rt_tick_get() - tick_delta;//计算已耗时间
timeout -= tick_delta;//计算剩余时间
if (timeout < 0)
timeout = 0;
}
}
/* set ptr */
mb->msg_pool[mb->in_offset] = value;//开始存放邮件
/* increase input offset */
++ mb->in_offset;
if (mb->in_offset >= mb->size)
mb->in_offset = 0;
/* increase message entry */
mb->entry ++;
/* resume suspended thread */
if (!rt_list_isempty(&mb->parent.suspend_thread))//唤醒接收线程
{
rt_ipc_list_resume(&(mb->parent.suspend_thread));
/* enable interrupt */
rt_hw_interrupt_enable(temp);
rt_schedule();
return RT_EOK;
}
/* enable interrupt */
rt_hw_interrupt_enable(temp);
return RT_EOK;
}
与接收函数类似,发送函数在邮箱满的时候会挂起发送线程。其它的参考接收函数,基本上差不多。
2.7 邮箱控制
[cpp]
/**
* This function can get or set some extra attributions of a mailbox object.
*
* @param mb the mailbox object
* @param cmd the execution command
* @param arg the execution argument
*
* @return the error code
*/
rt_err_t rt_mb_control(rt_mailbox_t mb, rt_uint8_t cmd, void *arg)
{
rt_ubase_t level;
RT_ASSERT(mb != RT_NULL);
if (cmd == RT_IPC_CMD_RESET)//重围邮箱
{
/* disable interrupt */
level = rt_hw_interrupt_disable();//关中断
/* resume all waiting thread */
rt_ipc_list_resume_all(&(mb->parent.suspend_thread));//唤醒所有挂起的接收线程
/* also resume all mailbox private suspended thread */
rt_ipc_list_resume_all(&(mb->suspend_sender_thread));//唤醒所有的发送线程
/* re-init mailbox */
mb->entry = 0;
mb->in_offset = 0;
mb->out_offset = 0;
/* enable interrupt */
rt_hw_interrupt_enable(level);
rt_schedule();
return RT_EOK;
}
return -RT_ERROR;
}
邮箱控制控制函数目前只支持重围操作,此操作过程与初始化过程基本上类似.
4 小结
邮箱相关源码主要是在发送与接收上。发送时,由于当前邮箱可能空间已满,放不下要发送的邮件,此时,不得不挂起当前发送线程(如果存在时间参数的话),只要在接收函数读取出一条邮件时才会唤醒它。同理,如果当前邮箱为空,则接收函数会挂起当前的接收线程,直到有新的邮件到达(在发送函数中唤醒接收线程)或等待超时。