|
发表于 2013-11-26 08:41:22
|
显示全部楼层
本帖最后由 mcu_lover 于 2013-11-26 08:47 编辑
其实楼主就是在传统的superloop基础之上添加了message 机制。
不知道楼主的任务有没有做优先级处理,如果没有处理的话,最坏的任务响应时间是所有任务轮巡一遍的时间。
这种结构,相比传统的superloop来说,扩展性,编写程序方便性确实有很大的提高。紧急事件靠中断处理,非紧急事件postmessage到队列,然后主循环处理。
SOS_PostHiPriMessage 发送3级消息 ,阻塞式;
SOS_PostLoPriMessage 发送4级消息 ,阻塞式;
楼主提到上面两个函数是阻塞式,是否意味着,在postmessage时候,直接调用了消息处理函数。这样就存在嵌套的可能性。应该分别提供阻塞式与非阻塞式的消息发送方式。
采用消息的方式进行程序设计,首先需要转变的就是程序设计思路,由传统的顺序处理,转变为事件处理。只有厘清了这些关系,方能最大程度利用其优势。
此外,消息机制的方式,在进行液晶界面设计时候,非常非常的方便。
static EUISTATE UITestModeChooseScreen(SYSMSG* pMsg)
{
EUISTATE eUIState = E_UI_STATE_NULL;
//----------------------------------------------------------//
static uint8 s_u8Cursor = 0, s_u8CurSel = 0;
uint8 u8Redraw = 0;
//---------------------------------------------------------//
switch(pMsg->uMsg)
{
//进入本界面时候,触发一次进入事件
case MSG_UI_ENTER_SCREEN:
//clear screen first
LcdClearScreen(0x00);
//可以从消息参数中得知,是从上层界面进入,还是从下层界面返回本界面
//从上层进入,一般需要初始化某些参数
if(pMsg->wm == UI_ENTER_SCREEN_FROM_PARENT)
{
//--------------------------------------------//
//show choose menu
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, u8Redraw, pMsg);
//-------------------------------------------//
}
//从下层界面返回,不需要初始化,当然也可以根据你自己的需要进行处理
else if(pMsg->wm == UI_ENTER_SCREEN_FROM_CHILD)
{
//--------------------------------------------//
//show choose menu
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, 1, pMsg);
//-------------------------------------------//
}
break;
//退出本界面时候,触发一次此消息,可以在此消息处理中,完成资源的回收
case MSG_UI_EXIT_SCREEN:
if(pMsg->wm == UI_EXIT_SCREEN_TO_PARENT)
{
s_u8Cursor = 0;
s_u8CurSel = 0;
}
break;
//自定义的消息事件,一般由程序中的其它任务产生。
case MSG_USER_TEST_MODE_CONFIRM:
//enter test screen
if(s_u8CurSel < sizeof(g_ModeItems)/sizeof(g_ModeItems[0]))
{
UIProcess_WndSwitch(g_ModeItems[s_u8CurSel].pTestFuncUI, UI_EXIT_SCREEN_TO_CHILD, s_u8CurSel);
}
break;
//屏幕刷新消息
case MSG_UI_PAINT_SCREEN:
LcdClearScreen(0x00);
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, 1, pMsg);
break;
//按键消息处理
case MSG_KEY:
if(pMsg->wm == (KEY_UI_ESC|KEY_DOWN))
{
//reset cursor
s_u8Cursor = 0;
s_u8CurSel = 0;
UIProcess_WndSwitch(UIMainScreen, UI_EXIT_SCREEN_TO_PARENT,0);
}
else if((pMsg->wm == (KEY_UI_RIGHT|KEY_DOWN)) ||
(pMsg->wm == (KEY_UI_RIGHT|KEY_REPEAT)))
{
s_u8CurSel += BITMAP_MAXITEMS_ON_SCREEN;
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, 1, pMsg);
}
else if((pMsg->wm == (KEY_UI_DOWN|KEY_DOWN)) ||
(pMsg->wm == (KEY_UI_DOWN|KEY_REPEAT)))
{
s_u8Cursor++;
s_u8CurSel++;
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, u8Redraw, pMsg);
}
else if((pMsg->wm == (KEY_UI_DOWN|KEY_UP)))
{
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, u8Redraw, pMsg);
}
else if((pMsg->wm == (KEY_UI_UP|KEY_DOWN)) ||
((pMsg->wm == (KEY_UI_UP|KEY_REPEAT))))
{
if(s_u8Cursor)
{
s_u8Cursor--;
}
if(s_u8CurSel)
{
s_u8CurSel--;
}
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, u8Redraw, pMsg);
}
else if((pMsg->wm == (KEY_UI_UP|KEY_UP)))
{
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, u8Redraw, pMsg);
}
else if((pMsg->wm == (KEY_UI_LEFT|KEY_DOWN)) ||
((pMsg->wm == (KEY_UI_LEFT|KEY_REPEAT))))
{
if(s_u8CurSel >= BITMAP_MAXITEMS_ON_SCREEN)
{
s_u8CurSel -= BITMAP_MAXITEMS_ON_SCREEN;
}
MenuChooseTestMode(g_ModeItems, BITMAP_MAXITEMS_ON_SCREEN, sizeof(g_ModeItems)/sizeof(g_ModeItems[0]), &s_u8Cursor, &s_u8CurSel, 1, pMsg);
}
else if(pMsg->wm == (KEY_UI_ENTER|KEY_DOWN))
{
UIProcess_DisplayChildWnd(UIConfirmChildScreen);
}
break;
//定时器消息处理
case MSG_TIMER:
break;
}
return eUIState;
}
上面这个函数,是一个菜单界面的处理过程,可以非常清晰地看到,在进入菜单屏幕界面,退出菜单屏幕界面,在菜单屏幕界面循环,按键处理,自定义消息处理等等。
消息可以根据具体应用进行扩展,这样传统的程序设计,就变成了基于消息方式的处理。 |
|