對于PC上的hello world,MCU上就是閃燈程序。之前介紹了事件驅(qū)動,那這里就以事件驅(qū)動的方式,來實(shí)現(xiàn)閃燈程序。代碼里會用到vsftimer模塊,也就是定時器模塊。VSF中大部分應(yīng)用直接使用main函數(shù)模板,這里先不做介紹,直接使用,跑一些代碼看看效果。也可以了解一下VSF中,一般應(yīng)用的寫法。
usrapp.h:
struct usrapp_t
{
struct vsfsm_t sm;
bool toggle;
};
extern struct usrapp_t usrapp;
void usrapp_srt_init(struct usrapp_t *app);
usrapp.c:
#include "vsf.h"
#include "usrapp.h"
struct vsfsm_state_t*
usrapp_led_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt);
struct usrapp_t usrapp =
{
.sm.init_state.evt_handler = usrapp_led_evt_handler,
.sm.user_data = &usrapp,
};
#define USRAPP_EVT_ON1S VSFSM_EVT_USER
struct vsfsm_state_t*
usrapp_led_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt)
{
struct usrapp_t *app = (struct usrapp_t *)sm->user_data;
switch (evt)
{
case VSFSM_EVT_INIT:
vsfhal_gpio_init(0);
vsfhal_gpio_config_pin(0, 1, GPIO_OUTPP);
vsftimer_create(sm, 1000, -1, USRAPP_EVT_ON1S);
// fall through
case USRAPP_EVT_ON1S:
if (app->toggle)
vsfhal_gpio_set(0, 1 << 1);
else
vsfhal_gpio_clear(0, 1 << 1);
app->toggle = !app->toggle;
break;
}
return NULL;
}
void usrapp_srt_init(struct usrapp_t *app)
{
vsfsm_init(&app->sm);
}
上面,usrapp_srt_init是應(yīng)用層的軟實(shí)時任務(wù)的初始化接口,這里初始化了app->sm,也就是由usrapp_led_evt_handler來處理各個事件。調(diào)用了vsfsm_init后,系統(tǒng)會發(fā)送VSFSM_EVT_INIT和VSFSM_EVT_ENTER分別表示狀態(tài)初始化,以及進(jìn)入狀態(tài),這里的狀態(tài)是app->sm.init_state,也就是初始狀態(tài)。當(dāng)然,目前所有的VSF應(yīng)用,都只是利用了初始狀態(tài)。
系統(tǒng)第一次調(diào)用usrapp_led_evt_handler的時候,是為了處理VSFSM_EVT_INIT事件,這里就只是初始化GPIO,并且注冊了一個1000ms定時器,并且會一直觸發(fā)(相當(dāng)于每隔1秒觸發(fā)一次),然后就退出了。下一個事件是VSFSM_EVT_ENTER,表示進(jìn)入init_state,不過這里不需要什么處理。之后系統(tǒng)就休眠了,1秒后,定時時間到,定時器模塊調(diào)用usrapp_led_evt_handler,并且事件為USRAPP_EVT_ON1S。在usrapp_led_evt_handler里處理USRAPP_EVT_ON1S就可以切換GPIO的輸出,實(shí)現(xiàn)閃燈的效果。usrapp_led_evt_handler永遠(yuǎn)返回NULL是因?yàn)椴恍枰鰻顟B(tài)切換,永遠(yuǎn)停留在init_state里。
PS: 是不是看不出代碼是在什么硬件上跑的?