通信机制
前面叙述了aCoral的互斥、同步机制,在实际的嵌入式应用软件开发过程中,仅有这两种机制还不够,线程之间、线程与中断服务子程序之间还需要通信机制。
所谓通信,是指线程之间或者线程与中断服务子程序之间的信息交互。
例如,线程A可能在执行过程中需要使用线程B(或者中断服务子程序产生)的数据,那么线程B如何把数据传给线程A使其得以执行呢?这里就需要通信机制发挥作用。
邮箱
邮箱(Mail Box)可以用来实现线程之间同步和通信功能。
假设线程2从邮箱中接收线程1发送过来的信息(该信息被称为邮件)。
线程2在同步点从邮箱中接收消息,如果线程1此时还没有执行到同步点,则邮箱中是不会有消息的,此时线程2会将自己挂起;
当线程1执行到同步点时,会向邮箱中发送一条信息,此时就会激活挂起的线程2,继续执行。
邮箱机制,一个线程将需要交互的信息发送到邮箱,另一个线程从邮箱中读取即可。
邮箱机制依赖于事件控制块acoral_evt_t,acoral_evt_t的Data成员就是用来挂载线程间传递的消息,当前版本aCoral的Data只支持存放一条信息。
创建邮箱
acoral_evt_t *acoral_mbox_create()
{
acoral_evt_t *event;
event = acoral_alloc_evt();
if(NULL == event)
return NULL;
event->type = ACORAL_EVENT_MBOX;
event->count = 0x00000000;
event->data = NULL;
acoral_evt_init(event);
return event;
}
发送信息到邮箱。
acoral_u32 acoral_mbox_send(acoral_evt_t *event, void *msg)
{
acoral_sr CPU_sr;
acoral_thread_t *thread;
if(NULL == event)
return MBOX_ERR_NULL;
HAL_ENTER_CRITICAL();
acoral_spin_lock(&event->spin_lock);
if(event->data != NULL)
{
acoral_spin_unlock(&event->spin_lock);
HAL_EXIT_CRITICAL();
return MBOX_ERR_MSG_EXIST;
}
event->data = msg;
thread = acoral_evt_high_thread(event);
if(thread == NULL)
{
acoral_spin_unlock(&event->spin_lock);
HAL_EXIT_CRITICAL();
return MBOX_SUCCED;
}
//释放等待任务,判断该邮箱等待队列中是否有线程在等待消息,如果有,就把最高优先级的等待线程更改为就绪状态,然后触发重新调度。
HAL_ENTER_CRITICAL();
acoral_spin_lock(&event->spin_lock);
if(event->data == NULL)
{
cur = acoral_running_thread;
acoral_evt_queue_add(event,cur);
acoral_unrdy_thread(cur);
acoral_spin_unlock(&event->spin_lock);
HAL_EXIT_CRITICAL();
acoral_sched();
HAL_ENTER_CRITICAL();
acoral_spin_lock(&event->spin_lock);
msg = event->data;
acoral_spin_unlock(&event->spin_lock);
HAL_EXIT_CRITICAL();
return msg;
}