本帖最后由 vsf 于 2018-4-5 00:21 编辑
VSF的核心是基于事件驱动的状态机构架,可以实现协作式和抢占式调度,任务可以共享堆栈也可以独立堆栈。并且,可以自由搭配,同时运行(系统同时具备抢占式和协作式、同时具备共享堆栈的任务和独立堆栈的任务)。以前介绍过好几次VSF里的事件驱动构架,这次准备一步一步,说明VSF核心的事件驱动是如何实现的。
事件驱动说了简单的话,就是由事件来驱动系统运行。那其实就分为2部分,一是事件的产生、二是事件的处理。是不是有点像生产者/消费者模型?
先说事件的处理。事件处理就是实现event_handler,来处理各个事件。简单的代码示例如下:
void event_handler(int event)
{
switch (event)
{
case EVENT_X:
break;
case EVENT_XX:
break;
......
}
}
这个够简单吧?就是收到什么事件,就做什么处理。
接下来就是看事件是如何产生的。先考虑一下普通的MCU系统是如何运行的。
逻辑上,MCU的运行,就是响应各种中断。
什么?你MCU里的代码没用中断?
恩,好的。首先,欢迎打脸。其次,你可以认为你的代码响应了MCU的复位中断。复位中断一般不可屏蔽,可以是复位后,从固定的地址开始执行代码;也可以从由复位向量决定的地址开始执行代码,这个依赖芯片的设计。而且,一般而言,复位中断执行的代码不会退出,因为最终执行到main里。对于RTOS,一般会启动任务调度;对于非OS系统,一般是一个while(1)循环。
VSF中的事件,就是由中断产生的,并且在中断事件处理中,可以产生更多的事件。当然,最终事件都会被处理完,否则系统就不会收敛了(类似癫痫)。
void X_IRQ(void)
{
post_event(EVENT_X);
}
在某个中断里,发送了EVENT_X事件。并且,最终调用到event_handler里处理。
这里就引入的另外一个问题,从post_event发送事件 到 调用event_handler处理事件之间,究竟发生了什么。
这里先讲最简模型,post_event发送事件的代码里,直接调用event_handler处理事件。
最简模型的应用:
void event_handler(int event)
{
switch (event)
{
case EVENT_X:
process_event_x();
break;
case EVENT_XX:
process_event_xx();
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();
}
这里,main函数以同样的优先级使能了X和XX中断(同一优先级意味着X和XX中断互相不抢占)。并且while(1)里一直调用休眠。在对应的中断处理函数里,直接调用post_event发送对应的事件。然后post_event里,直接调用event_handler处理事件。这个系统下,process_event_x和process_event_xx都会独占CPU,并且以协作式的方式运行。
|