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

[复制链接]
941|1
 楼主| vsf 发表于 2018-4-5 22:23 | 显示全部楼层 |阅读模式
本帖最后由 vsf 于 2018-4-5 22:25 编辑

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

  2. void event_handler(int event)
  3. {
  4.   switch (event)
  5.   {
  6.   case EVENT_X:
  7.     process_event_x();
  8.     evtq_push(&evtq, EVENT_LOW_PRIORITY);
  9.     break;
  10.   }
  11. }

  12. void post_event(int event)
  13. {
  14.   event_handler(event);
  15. }

  16. void X_IRQ(void)
  17. {
  18.   post_event(EVENT_X);
  19. }

  20. void event_handler_low_priority(int event)
  21. {
  22.   switch (event)
  23.   {
  24.   case EVENT_LOW_PRIORITY:
  25.     break;
  26.   }
  27. }

  28. void main(void)
  29. {
  30.   enable_X_IRQ();

  31.   while (1)
  32.   {
  33.     if (evtq_has_event(&evtq))
  34.     {
  35.       int event = evtq_pop(&evtq);
  36.       event_handler_low_priority(event);
  37.     }
  38.     else
  39.       vsfhal_core_sleep();
  40.   }
  41. }
在这个示例中,定义了一个事件队列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

粉丝
快速回复 在线客服 返回列表 返回顶部