MTK 消息机制
MTK的架构其实有4大层次,最上一层为MMI层,此层包括各种框架已经应用(例如GUI框架,字体引擎等),下一层为L4层,此层作为MMI层与协议以及驱动通信的一扇大门。L4层细分为L4A以及L4C,L4A是一层抽象层,用来接收来自MMI层的请求,然后解释并传给L4C(L4控制层),让其处理,然后L4C再往下一层发送包装好的请求。这层为协议栈以及驱动层,包括UEM(用户设备管理),PHB(电话簿管理),SMU(安全管理单元,管理SIM以及STK),CSM(通话服务管理,管理打电话),RAC(注册接入控制,管理网络注册服务),SMSAL(短信应用层),TCM(终端上下文管理,管理PDP上下文激活,维护等),ENG(工程模式以及信息记录)。在下面的一层为OS层,MTK对于OS还有在其上面进行一次封装(KAL,Kernal Abstract Layer),主要目的是为了便于移植,调试,与PC对联等。同时,它上面还会封装一层OSL(用来给PC模拟器用的)。
MTK的任务之间是通过传递消息来合作的,一般都以Queue来消息队作为列。
消息队列分为三种:
一种是外部队列,作为任务与任务之间的一种消息队列,消息的传送是在不同任务之间执行的。一般采用OslReceiveMsgExtQ(弃用)msg_receive_extq,以及OslMsgSendExtQueue来发送接收消息。
一种是内部队列,作为任务内的一种消息队列,消息是在任务内传递的,一般接受发送的接口为receive_msg_int_q(已经弃用),使用msg_receive_intq()和msg_send_int_queue。
最后一种是循环队列,仅用于MMI部分,用于MMI 务任的消息,一般采用OslReadCircularQ以及OslWriteCircularQ。MMI的任务初始化为MMI_Init,主要完成创建信号量,建立定时器,建立UI的包装链接(就是把一系列的函数对应与相关的函数指针),而接着就是MMI_Task的运行了,主要是就是接收来自L4C的消息以及内部消息,先首先预处理一些特殊的消息,然后把别的消息留给ProtocolEventHandler来处理,并且针对不同的电源模式有不同的唯一接口。
MMI循环队列
MMI任务需要监听内部循环消息队列的消息,也有监听外部消息。为了能处理外部消息(来自L4C的消息),必须要针对不同的消息注册不同的处理函数。一般采用SetProtocolEventHandler。要往L4C发消息,一般的步骤为:创建一个本地参数缓存,填好必须的参数信息,利用外发消息的函数来发送消息到L4C。
MMI层的架构
MMI层的架构分为大致3块。一块为Framework,一块为Application,一块为UI。
Framework主要提供了:事件处理模块,窗口历史管理,OSL封装,NVRAM接入管理,文件系统管理。
Application块主要为各种应用,以及一些窗口模板,在MTK上称为Category Screens,这些模板都是一些常用到的,例如菜单,文本编辑,宫格等。UI层包括Image的解码,Font字体引擎,Theme主题引擎,资源管理。比较底层的为GDI接口以及Pixtel接口,这些都属于图形库的,算是一套2D图形引擎。
Framework块与Application块的互通主要是基于事件处理以及请求,L4C的消息通过队列,然后到达Framework块,Framework的事件处理会依据Application块的应用注册的事件函数信息来调用相应的处理函数来驱动Application的运作。而Application则调用UI层来达到图形的显示。
MMI事件
OSL Wrapper是一种对操作系统的封装,提供队列处理以及定时器管理。MMI处理的事件分为三种。一种是协议栈事件,这是基本的事件,每个事件都有唯一的ID代表。按键事件,也算是一种协议栈事件,单独提出来说,主要是因为此类事件是一种使用频率最高的事件,处理有特殊对待。最后一种是高亮事件(Hilite Event),此事件是用户发起的事件,基于按键事件产生的,关联相应的提示信息。其实因为按键消息属于协议栈的消息之一,故此其也是按照L4C事件的流程,只不过在Framework那里还加了一道处理,用以转换成对应的MMI按键消息。窗口历史机制是,每次进入一个新窗口的时候,都会预先把当前窗口的一些基本信息给保留到一个历史栈中,这些基本信息为窗口的进入函数,窗口ID,以及数据缓存(用来保存一些当前数据,确保界面回退后,原界面信息不变)。
NvRam
NvRam是一种信息的模块,每个信息对应一个ID。ID定义在custom_mmi_default_value.h中,默认的数据定义在file_Nvram_cust_pack.c中。记录保存在nvram_user_config.c中。NVRAM是通过L4C发消息来处理的,对于MMI,其是使用NVRAM manager提供的接口封装来读存数据的。NVRAM是跑在单独的一个任务上面去的。文件系统是通过一个包装接口来访问的。模板窗口机制是MTK特有的,MTK准备了很多类别的模板窗口,一本的格式类似ShowCategoryXXXScreen, RedrawCategoryXXXScreen, ExitCategoryXXXScreen。第一个函数,主要负责注册事件处理函数,对UI做预处理(例如初始化,填数据等),最后会呼叫第二个函数,主要就是把界面的元素都给绘画出来。最后一个函数的主要作用是做退出界面的清扫工作。新的MTK窗口的处理方法是采用Draw Manager。它把界面的元素都作为控件看待,并且把界面的空间预先存放到一个表中,配合这些控件的坐标集以及控制方式集,并存放到资源文件中,这样可以做到界面可以快速的,集中的修改。同样一个模板界面,可以拥有不同的这些集合,以达到适合不同的应用。至于前面提及的redraw, history, exit函数,以前很多都是不同模板采用不同的,现在都大部分集中替换为公共的:dm_redraw_category_screen, dm_get_history / dm_get_history_size 和 dm_exit_category_screen。一般应用绘制界面的流程如下:应用通过调用把ScreenID以及CategoryID发送给Draw Manager,然后Draw Manager通过Screen ID以及CategoryID找到对应的坐标以及控件元素集,如果有的话,还可以找到对应的控制集,并返回给Draw Manager,然后Draw Manager自动根据这些表格来绘制界面。MTK的资源操作,对于字符串,所有字符串(包括多国语言的)都在ref_list.txt上面,用户如果需要增加一个字符串,则要做:1.添加一个ID到与应用相关的字符串枚举定义那里,枚举的起始值必须以相关APP的基址,以确保ID的全局唯一性。2 针对这个ID在ref_list.txt那里增加对应的字串(多国语言),最后在用ADD_APPLICATION_STRING2吧其关联起来。图片资源的流程与字串很相似,增加ID到枚举定义中,以APP_BASE为基址确保全局唯一,在把图片放到对应的目录去,调用ADD_APPLICATION_IMAGE2来关联起来。资源还有菜单资源(定义菜单布局,以及选中后进入的函数),铃声资源(与图片资源相似),还有皮肤布局(主要是MP3,MP4,FM,Camera),主题(ThemeRes.c)以及字体(FontRes.c)。铃声的配置可以看imy.txt文件,主要数组为mtk_resource_imelodys[], 还有midi.txt, mtk_resource_midis[]。还有各种别的声音信息,可以看相关的txt文件,利用工具AudioResGen.exe来 生成对应的数组,在进行替换原有的数组即可。MTK上面有许许多多的第三方应用,第三方应用如输入法,语言,Java,Wap等,这些功能的开关都放在MMI_Feature$Project.h那里以及$custom_$project.mak那里。目前MTK采用ADS V1.2的编译器,需要ActivePer 5.6.1的环境,最好是WinXP的开发环境。
GSM2.mak文件是一个很重要的文件 ,里面涉及到make执行的目标的第一道门。而$Customer_$project.mak则是许多应用的以及功能的开关。
在Make目录下面的每个模块下面有四个文件:
.def .inc, .lis, .pth分别是该模块的开关,引用到的头文件路径,需要编译的源文件,以及存放路径。
一般的编译命令为:
make [custom = "customer"] "project" "action" ["modules"]
custom = mtk
project = l1s
= gsm
= gprs
= basic
action = new
= update
= remake
= label_build
= clean
= get
= codegen