|
飞利浦软体实现主要是基于MCC sequence这样一种机制,飞利浦软体利用MCC sequence 来控制软体的函数调用,再通过所调用的函数传递消息,以实现其各项功能。
在MMI这个文件夹中出现了很多*.h??的文件,这在标准C里是没有的,所以很多人不是很理解。其实这是用来区分程序中所有定义的变量或函数的头文件。其中包括:*.h ; *.hec ; *.hem ; *.hep ; *.het ; *. hev ; *.hic ; *. him ; *.hip ;*hit ; *. hiv。
其中
*.h文件是标准C中很常见的头文件,它include模块中所有的文件。
*.hec文件中主要定义一些外部的宏定义。
*.hem文件中主要是定义一些外部结构体的宏定义。
*.hep文件中主要是定义外部函数。
*.het文件中主要是定义外部结构体。
*. hev文件中主要是定义外部变量。
*.hic文件中主要是定义内部的宏定义。
*. him文件中主要是定义一些内部结构体的宏定义。
*.hip文件中主要是定义内部函数。
*.hit文件中主要是定义内部结构体。
*. hiv文件中主要是定义内部变量。
2.MMI软体结构
我们就拿Lk_mcc.hev当例子具体的讲解一下。首先我们引入MCC sequences的概念,下面就拿出一个具体的例子。
t_mcc mcc_lk_main_menu[] =
{
MC_MCC_DISPLAY(WIN_E, DS_EMPTY, WT_WORD),
MC_MCC_NAVIGS(NAVIG_MAINMENU,0,0,P_MAINMENU_1, mcc_dir_main_menu),
MC_MCC_NAVIG(NAVIG_MAINMENU,1,0,P_MAINMENU_2, mcc_sms_main_menu),
MC_MCC_NAVIG(NAVIG_MAINMENU,2,0,P_MAINMENU_3, mcc_aoc_main_menu),
MC_MCC_NAVIG(NAVIG_MAINMENU,3,0,P_MAINMENU_4, mcc_ss_main_menu),
MC_MCC_NAVIG(NAVIG_MAINMENU,4,0,P_MAINMENU_5
mcc_set_clock),
MC_MCC_NAVIG(NAVIG_MAINMENU,5,0,P_MAINMENU_6, mcc_set_main_menu),
MC_MCC_NAVIG(NAVIG_MAINMENU,6,0,P_MAINMENU_7, mcc_set_miscellaneous_menu),
MC_MCC_NAVIGE(NAVIG_MAINMENU,7,SG_ST,DS_ST_MAINMENU, mcc_st_main_menu),
};
这段代码就是显主菜单功能的。首先我们来看看t_mcc的结构体
typedef const struct mcc_s {
u8 v_ctrl_code;
u8 v_attrib1;
u8 v_attrib2;
u16 v_attrib3;
u16 v_attrib4;
const struct mcc_s *p_link;
} t_mcc;
这个结构体实际上就是一个链表,
u8 v_ctrl_code :表示MCC所用的函数在哪个模块里。
u8 v_attrib1:表示在这个结构链表中的第一位。
u8 v_attrib2:表示在这个结构链表中的第二位。
u16 v_attrib3:表示在这个结构链表中的第三位。
u16 v_attrib4:表示在这个结构链表中的第四位。
const struct mcc_s *p_link;:表示连接。
这样我们会发现t_mcc mcc_lk_main_menu[]表示的是,用t_mcc这种结构定义的数组mcc_lk_main_menu[]。数组里面的所有成员都是t_mcc这种结构。了解了所有数组成员的结构后,接下来就具体的分析一下这些代码。
MC_MCC_DISPLAY(WIN_E, DS_EMPTY, WT_WORD)
MC_MCC_DISPLAY的定义:
#define MC_MCC_DISPLAY(window,string,wrap) MCC_DISPLAY, ACT_SG, window, string, wrap, 0
这样我们就很清楚它的结构了。接下来我们再查MCC_DISPLAY定义( case MCC_DISPLAY: )这里调用了很多有关显示的函数和参数,可以用上面讲过的方法来具体的看一下它们是如何定义的。这里我们只介绍WIN_E, DS_EMPTY, WT_WORD这三个参数。
WIN_E它代表结构体t_mcc中的v_attrib1,它定义在look.hec中,它表示LCD的编辑区域。在这个文件中我们可以找到相关的所有的参数的定义。
DS_EMPTY它代表结构体t_mcc中的v_attrib2,也是定义在look.hec中,它代表一个空字符。
WT_WORD它代表结构体t_mcc中的v_attrib3,也是定义在look.hec中,它代表要显示的是一个字符型变量。
这样这段代码就清楚了,它是为了清空编辑区域里所有的文字。接下来我们来分析一下这行代码:MC_MCC_NAVIGS(NAVIG_MAINMENU,0,0,P_MAINMENU_1, mcc_dir_main_menu),我们很快就能找到定义:CASE MCC_NAVIGS:这里对NAVIG_MAINMENU(主菜单)、NAVIG_FASTMENU(快捷菜单)都有了详细的定义,lk4_7MenuDisplayOnLCD()的完成,是用的一些MMI与DRIV之间的消息传递。我们将在下面做介绍。
其中在MC_MCC_NAVIGS 的结构体中最后的一个变量mcc_dir_main_menu是用来把程序连接到电话簿中的,这一点我们可以在t_mcc这个结构中看到。也就是说,当用户选种电话簿时,它会把程序连接到电话簿功能模块中。
需要注意的是MC_MCC_NAVIGS 、MC_MCC_NAVIG 、MC_MCC_NAVIGE三者表示主菜单的开始到结束。到这里大家应该对这个MCC sequences是怎样运作,函数之间怎样相互调用有个初步的了解。
3.消息传递
上面我们曾经提到过,消息传递的概念,那么为什么要传递这些消息,这些消息又是如何传递的呢?我们将在这里用实际例子加以解释。
在讲主菜单功能时,我们提到过主菜单和快捷菜单的显示问题。其中程序中用到了lk4_7MenuDisplayOnLCD()这个函数,在函数体中我们可以看到这样一段代码:
MC_RTK_SEND_MSG_TO_PROCESS( PROCESS_MMI, 0, PROCESS_LCD, 0, MOBI_LCD_MENU_DISPLAY_REQ, (t_MsgHeader *)pl_MenuDisplay );这就是实现MMI对DRIVER调用的代码。我们主要介绍MOBI是如何传递的。
我们先找到MOBI_LCD_MENU_DISPLAY_REQ在DRIV的文件夹下的定义:
MC_PCC_HEADER(PROCESS_MMI,PROCESS_LCD,
MOBI_LCD_MENU_DISPLAY_REQ,MC_RTK_PROCESS_OPERATION
(PROCESS_LCD,F_LCD_MENU_DISPLAY_REQ ) )
MC_PCC_BEGIN_STRUC( t_LcdFastMenuDisplay )
MC_PCC_FIELD( u8, MenuType )
MC_PCC_FIELD( u8, StartIcon )
MC_PCC_FIELD( u8, ContrastIcon )
MC_PCC_END_STRUC( t_LcdFastMenuDisplay)
大家可以自己去查找每个参数的定义。
另外我们也可以查到:
MC_RTK_OFSM(MOBI_LCD_MENU_DISPLAY_REQ,hsc1_DisplayMenuHandler,SAME)
这就是根源所在,原来这个MOBI是通过hsc1_DisplayMenuHandler完成它的使命的。这就是MMI如何用MOBI调用HANDLER中的函数来实现消息传递的。接下来HANDLER部分再调用DRIV中的函数来最终完成显示功能。
和MOBI一样大家经常看到的APPI也是用同样的方法来实现消息传递的。在MMI中的*_mcc.hev文件中我们经常会看到MC_MCC_BSRP这个结构,它主要的是用来实现APPI的消息传递的。 |
|