设为首页 加入收藏

TOP

IPC机制之事件源码分析(三)
2013-07-23 09:04:19 来源: 作者: 【 】 浏览:299
Tags:IPC 机制 事件 源码 分析

 

  3.6 接收事件

  [cpp] view plaincopyprint

  /**

  * This function will receive an event from event object, if the event is

  * unavailable, the thread shall wait for a specified time.

  *

  * @param event the fast event object

  * @param set the interested event set

  * @param option the receive option

  * @param timeout the waiting time

  * @param recved the received event

  *

  * @return the error code

  */

  rt_err_t rt_event_recv(rt_event_t event,

  rt_uint32_t set,//感光趣的事件集

  rt_uint8_t option,//过滤模式

  rt_int32_t timeout,

  rt_uint32_t *recved)

  {

  struct rt_thread *thread;

  register rt_ubase_t level;

  register rt_base_t status;

  RT_DEBUG_NOT_IN_INTERRUPT;//确保此函数不在ISR中使用

  /* parameter check */

  RT_ASSERT(event != RT_NULL);

  if (set == 0)//如果不对任何事件感兴趣则直接返回

  return -RT_ERROR;

  /* init status */

  status = -RT_ERROR;

  /* get current thread */

  thread = rt_thread_self();//获取当前线程

  /* reset thread error */

  thread->error = RT_EOK;//重置线程的err码

  RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(event->parent.parent)));

  /* disable interrupt */

  level = rt_hw_interrupt_disable();//关中断

  /* check event set */

  if (option & RT_EVENT_FLAG_AND)//如果过滤选项为逻辑与

  {

  if ((event->set & set) == set)//判断是否已接收到所有感兴趣的事件

  status = RT_EOK;

  }

  else if (option & RT_EVENT_FLAG_OR)//如果过滤选项为逻辑或

  {

  if (event->set & set)//判断是否接收到任一感兴趣的事件

  status = RT_EOK;

  }

  if (status == RT_EOK)//如果接收事件已成功

  {

  /* set received event */

  *recved = (event->set & set);//保存接收到的事件集到recved指向的空间

  /* received event */

  if (option & RT_EVENT_FLAG_CLEAR)//清除接收到的事件集

  event->set &= ~set;

  }

  else if (timeout == 0)//如果没有接收到事件,且等待参数为0,则立即返回错误

  {

  /* no waiting */

  thread->error = -RT_ETIMEOUT;

  }

  else//如果没有接收到事件,且等待参数不为0,则需要阻塞当前线程

  {

  /* fill thread event info */

  thread->event_set = set;

  thread->event_info = option;

  /* put thread to suspended thread list */

  rt_ipc_list_suspend(&(event->parent.suspend_thread),//挂起当前线程

  thread,

  event->parent.parent.flag);

  /* if there is a waiting timeout, active thread timer */

  if (timeout > 0)

  {

  /* 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));//启动定时器

  }

  /* enable interrupt */

  rt_hw_interrupt_enable(level);//开中断

  /* do a schedule */

  rt_schedule();//开始重新调度,此时当前线程才真正挂起

  if (thread->error != RT_EOK)//只有两种可能才能运行到这:1 定时器超时,当前线程还是没有等到事件的到达,此时,定时器的超时回调处理函数内会将thread的error设置为-RT_ETIMOUT;2:事件到达,当前线程被唤醒,此时thread的error还是保持原值不变

  {

  /* return error */

  return thread->error;//没有等到事件到达,则直接返回错误码

  }

  /* received an event, disable interrupt to protect */

  level = rt_hw_interrupt_disable();//开中断,此时已等到事件的到来

  /* set received event */

  *recved = thread->event_set;//保存接收到的事件集到recved指向的内存

  }

  /* enable interrupt */

  rt_hw_interrupt_enable(level);//开中断

  RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(event->parent.parent)));

  return thread->error;

  }

  /**

  * This function will receive an event from event object, if the event is

  * unavailable, the thread shall wait for a specified time.

  *

  * @param event the fast event object

  * @param set the interested event set

  * @param option the receive option

  * @param timeout the waiting time

  * @param recved the received event

  *

  * @return the error code

  */

  rt_err_t rt_event_recv(rt_event_t event,

  rt_uint32_t set,//感光趣的事件集

  rt_uint8_t option,//过滤模式

  rt_int32_t timeout,

  rt_uint32_t *recved)

  {

  struct rt_thread *thread;

  register rt_ubase_t level;

  register rt_base_t status;

  RT_DEBUG_NOT_IN_INTERRUPT;//确保此函数不在ISR中使用

  /* parameter check */

  RT_ASSERT(event != RT_NULL);

  if (set == 0)//如果不对任何事件感兴趣则直接返回

  return -RT_ERROR;

  /* init status */

  status = -RT_ERROR;

  /* get current thread */

  thread = rt_thread_self();//获取当前线程

  /* reset thread error */

  thread->error = RT_EOK;//重置线程的err码

  RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(event->parent.parent)));

  /* disable interrupt */

  level = rt_hw_interrupt_disable();//关中断

  /* check event set */

  if (option & RT_EVENT_FLAG_AND)//如果过滤选项为逻辑与

  {

  if ((event->set & set) == set)//判断是否已接收到所有感兴趣的事件

  status = RT_EOK;

  }

  else if (option & RT_EVENT_FLAG_OR)//如果过滤选项为逻辑或

  {

  if (event->set & set)//判断是否接收到任一感兴趣的事件

  status = RT_EOK;

  }

  if (status == RT_EOK)//如果接收事件已成功

  {

  /* set received event */

  *recved = (event->set & set);//保存接收到的事件集到recved指向的空间

  /* received event */

  if (option & RT_EVENT_FLAG_CLEAR)//清除接收到的事件集

  event->set &= ~set;

  }

  else if (timeout == 0)//如果没有接收到事件,且等待参数为0,则立即返回错误

  {

  /* no waiting */

  thread->error = -RT_ETIMEOUT;

  }

  else//如果没有接收到事件,且等待参数不为0,则需要阻塞当前线程

  {

  /* fill thread event info */

  thread->event_set = set;

  thread->event_info = option;

  /* put thread to suspended thread list */

  rt_ipc_list_suspend(&(event->parent.suspend_thread),//挂起当前线程

  thread,

  event->parent.parent.flag);

  /* if there is a waiting timeout, active thread timer */

  if (timeout > 0)

  {

  /* 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));//启动定时器

  }

  /* enable interrupt */

  rt_hw_interrupt_enable(level);//开中断

  /* do a schedule */

  rt_schedule();//开始重新调度,此时当前线程才真正挂起

  if (thread->error != RT_EOK)//只有两种可能才能运行到这:1 定时器超时,当前线程还是没有等到事件的到达,此时,定时器的超时回调处理函数内会将thread的error设置为-RT_ETIMOUT;2:事件到达,当前线程被唤醒,此时thread的error还是保持原值不变

  {

  /* return error */

  return thread->error;//没有等到事件到达,则直接返回错误码

  }

  /* received an event, disable interrupt to protect */

  level = rt_hw_interrupt_disable();//开中断,此时已等到事件的到来

  /* set received event */

  *recved = thread->event_set;//保存接收到的事件集到recved指向的内存

  }

  /* enable interrupt */

  rt_hw_interrupt_enable(level);//开中断

  RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(event->parent.parent)));

  return thread->error;

  }

  接收线程比较简单,如果接收到事件则判断它是否为它关心的事件,如果是,则保存事件,如果不是,则当没有接收到事件情况一起处理。接下来就是没有事件到达的情况,还是老规矩,先判断时间参数是否为0,如果是则直接返回超时,如果不是,则设置一定时器然后启动它,接着重新调度线程,然后根据当前线程的error值是否为RT_EOK来判断是否有新的并且符合条件的事件到达,如果不是,则返回错误码,如果是,则保存事件,最终返回OK。

        

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++大整数排序 下一篇强转是+0.01的习惯

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: