本帖最后由 vsf 于 2018-4-5 22:01 编辑
在事件驱动的系统中,事件是可以有优先级的,高优先级的事件先处理,低优先级的事件后处理。
比如,在之前的最简模型中,process_event_x会先处理高优先级的代码,然后发送低优先级事件EVENT_LOW_PRIORITY。
void process_event_x(void)
{
high_priority_code();
post_event(EVENT_LOW_PRIORITY);
}
void event_handler(int event)
{
switch (event)
{
case EVENT_X:
process_event_x();
break;
case EVENT_XX:
process_event_xx();
break;
case EVENT_LOW_PRIORITY:
low_priority_code();
break;
}
}
void post_event(int event)
{
event_handler(event);
}
void X_IRQ(void)
{
post_event(EVENT_X);
}
void XX_IRQ(void)
{
post_event(EVENT_XX);
}
void main(void)
{
enable_X_IRQ();
enable_XX_IRQ();
while (1)
vsfhal_core_sleep();
}
这个系统中,EVENT_X和EVENT_XX都是在中断里直接发送,是高优先级的事件,而EVENT_LOW_PRIORITY在设计上是低优先级的事件。
但是通过目前的代码,系统在处理EVENT_LOW_PRIORITY的时候,实际也是位于X_IRQ中断里,这时候XX_IRQ并不能被触发(因为X_IRQ和XX_IRQ工作于协作模式,不能抢占)。所以,上述代码是无法实现事件的优先级的。那么要怎么样才能实现事件的优先级呢?
这里要解决的是2个问题:
1. 处理高优先级事件的时候,如何发送低优先级事件
2. 处理低优先级事件的时候,如何发送高优先级事件
解决方案:
处理高优先级事件的时候,如果需要发送低优先级事件,那么低优先级事件不能马上处理,那就需要有一个低优先级的事件队列来保存事件。
处理低优先级事件的时候,如果需要发送高优先级事件,有2种方法
1. 不是用高优先级事件队列,那么可以在关闭X_IRQ和XX_IRQ的情况下,在低优先级事件处理代码中,直接post_event高优先级事件。由于中断被关闭,这里可以保证处理高优先级的中断不会被抢占。
2. 是用高优先级事件队列,事件进入高优先级事件队列的时候,自动激活,然后优先处理高优先级事件。
VSF里,事件被分为2种优先级,软实时和非实时。这2个不同的实时性的事件,处理的位置不同。软实时一般在低优先级中断里处理,非实时在main函数里处理。当然,还有硬实时,硬实时一般不用事件,在高优先级中断里直接处理。
这里要结合下一章,VSF中的事件队列实现,才能完全理解不同的优先级的事件是如何处理的。
|