打印

VSF从入门到XX系列--(5)事件驱动.事件队列

[复制链接]
735|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
vsf|  楼主 | 2018-4-5 22:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 vsf 于 2018-4-5 22:25 编辑

前一章讲了,应用需求中,事件需要具备不同的优先级。比如,串口接收数据事件中,先收下数据,然后发送低优先级的GUI更新事件。GUI更新事件的处理会占用大量CPU,所以不适合在串口接收事件中直接处理。而最简事件驱动模型是不能支持事件的优先级的。
VSF中使用了事件队列来实现这个功能。简单说的话,就是实现一个低优先级的事件队列,在高优先级事件处理的过程中,发送的低优先级事件,都放到低优先级事件队列了。事件队列实质是一个事件的fifo,先产生的事件,会先进入事件队列,也会先拿出来处理。
struct event_queue_t evtq;

void event_handler(int event)
{
  switch (event)
  {
  case EVENT_X:
    process_event_x();
    evtq_push(&evtq, EVENT_LOW_PRIORITY);
    break;
  }
}

void post_event(int event)
{
  event_handler(event);
}

void X_IRQ(void)
{
  post_event(EVENT_X);
}

void event_handler_low_priority(int event)
{
  switch (event)
  {
  case EVENT_LOW_PRIORITY:
    break;
  }
}

void main(void)
{
  enable_X_IRQ();

  while (1)
  {
    if (evtq_has_event(&evtq))
    {
      int event = evtq_pop(&evtq);
      event_handler_low_priority(event);
    }
    else
      vsfhal_core_sleep();
  }
}
在这个示例中,定义了一个事件队列evtq,在高优先级EVENT_X事件处理中,会把EVENT_LOW_PRIORITY低优先级事件发送到evtq里去。然后,event_handler退出,最终X_IRQ退出,由于MCU被唤醒了,继续运行main中的代码。这里main里的代码发现事件队列里有事件,就拿出事件,调用低优先级的event_handler_low_priority处理。

这里就是VSF中,实现抢占式的原理。main里运行的低优先级事件队列,可以被中断抢占。VSF中的抢占特性,其实就只是MCU的中断抢占main函数的特性而已。

另外,如果把中断里的事件处理,也看成是一个事件队列的话(事件队里的特例,事件一旦push进队列,会马上pop出来处理)。那其实具备抢占能力的是事件队列,而不是事件本身。事件队列具备抢占能力,也只是因为低优先级事件队列是在main函数中处理,这个用于实现非实时事件队列。而在低优先级中断里,处理的事件,可以抢占main中的代码,这个用于实现软实时事件队列。

使用特权

评论回复

相关帖子

发新帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

vsf

27

主题

60

帖子

6

粉丝