1、开发归档mtk 学习开发归档 011.1. 各模块功能Application layer: 包含用户定义的应用程序Framework layer: 包含消息处理和事件操作。 。UI Layer: 包含 ui 相关联的函数MMI Queue: 协议栈 /L4 将事件写入其中,MMI Task 从中读取事件。L4/NS Queue: MMI Task 将事件写入其中,L4 task/Network Simulator 从中读取事件。MMI Task 执行流程:1. 等待消息事件发送给 MMI 队列2. MMI 队列中的消息由协议占发送3. Framework 层执行事件。4. Framework
2、层出发应用层的回调函数应用层对接收事件做出回应(以按键事件为例子)1.1. L4 - MMI Task说明:1. 协议占向 MMI Queue 中写入事件2. MMI Task 从 MMI Queue 中读取Framework 层为最新注册事件调用回调函数应用层接收到按键事件并做出回应1.1. MMI-L4(应用程序发送播放声音请求)说明:1.应用层向 framework 层发送请求,使其向 L4 队列传送信息2.Framework 将消息写入 L4 队列3.L4 从 L4 队列中读取事件并播放请求的声音1.1.1. Framework 层1. 为应用程序提供事件句柄 API 来管理事件句柄键
3、盘事件句柄 API协议事件句柄 APIMisc.Handlers- Exit HandlersSet Exit handlers for particular screenExecute Exit handler for current screenClear Crrent Exit Handler2. History API3. Queue API- Create QueueoslMsgqid OslIntCreateMsgQ(PS8 queue_name,U32 max_msg_size,U32 max_msgs)- Write to QueueOSLSTATUS OslIntWriteM
4、sgQ(oslMsgqidmsgqid,void *msgPtr,U32 msgSize, OSLWAITMODE wait_mode)- Read from QueueOSLSTATUS OslIntReadMsgQ(oslMsgqidmsgqid,void *msgPtr, U32 *msgSize,OSLWAITMODE wait_mode)1.1.2. UI 层2. 窗口函数Function to enter : void ShowCategoryXScreen(argument list);Function to exit : void ExitCategoryXScreen(voi
5、d);Function to get the size of history : BYTE* GetCategoryXHistory(BYTE* buffer);Function to get the history : INT GetCategoryXHistorySize(void);ShowCatagoryXXXScreen注册事件句柄预处理 UI 元素- 调用重绘函数RedrawCategoryXXXScreen- 使用 GDI 函数绘制窗口ExitCategoryXXXScreen- 重新设置函数指针其他操作依据不同的窗口而定GetCategoryXXXHistorySize- 用来
6、返回 gui buffer 和 input buffer 的大小GetCategoryXXXHistory- 用来返回 gui buffer 和 input buffer 的数据GetCategoryXXXData- 用来返回 input buffer- 改变 softkey labelsVoid ChangeLeftSoftkey(STRING_ID s,IMAGE_ID i);Void ChangeRightSoftkey(STRING_ID s, IMAGE_ID i);- 改变 softkey functionsVoid SetLeftSoftkeyFunction(void(*f)(
7、void),KEY_EVENT_TYPE k);Void SetRightSoftkeyFunction(void(*f)(void),KEY_EVENT_TYPE k);- 在菜单中获得高亮显示项INT GetHighlightedItem(void); 设置高亮显示效果Void SetHighlightedItem(INT item_index); 注册高亮显示句柄Void RegisterHighlightHandler(void(*fptr)(INT item_index); 移除高亮显示句柄Void ClearHighlightHandler(void);书写应用程序- 资源在 Pi
8、xtelDataTypes.h 中定义 APP_BASE定义各种资源 IDScreensStringsImagesMenu Items (GlobalMenuItem.h)书写资源生成函数Resource Generator(PopulateRes.c)调用使用宏定义 ADD_APPLICATION_XXX修改 ResGenerator 的”Makefile”和”readexcel.c”- Make file在 make file 中添加关键宏定义在 MMI_features$Proj.h 中添加 feature macro添加库文件(COMPOBJS)添加编译列表创建目录 in mcumak
9、e添加目录名到 CUS_REL_SRC_COMP- Initialization初始化函数1. InitializeAll(Not all)在现有工程主要工作:ADD_APPLICATION (AddApp 函数) 在 framework 中来添加新的应用程序。void AddApp(U32 nId, S8 *pName, U16 nMinId, U16 nMaxId)PopulateXXX :为各个应用程序加载其各种资源 (字符串,图片,菜单项)2. 初始化各种事件句柄高亮显示句柄协议事件句柄- Entry and Exit标准入口函数调用执行当前的退出句柄获得当前窗口的 GUI buffe
10、r获得窗口显示元素注册高亮显示句柄调用窗口函数绘制窗体设置退出句柄标准出口函数创建 History 节点将入口函数保存入 History 节点中填充输入 buffer 和 History 节点中的 GUI buffer保存 history高亮句柄改变左键和右键句柄mtk 学习开发归档 021. MMI 和 L4 通信1.1. 如何通信Send/Receive messages thru the message Queue.#define OslMsgSendExtQueue msg_send_ext_queue#define OslReceiveMsgExtQ receive_msg_ext_
11、qSetProtocolEventHandler(FuncCB, msg_id);1.2. 通信数据typedef struct ilm_struct oslModuleType oslSrcId; / Source module ID.oslModuleType oslDestId; / Destination module ID.oslMsgType oslSapId; / service access point.oslMsgType oslMsgId; / message name ID.oslParaType *oslDataPtr; /local parameter buffero
12、slPeerParaPtr *oslPeerBuffPtr; /peer buffer pointer ilm_struct;1.3. 如何从 MMI Queue 中侦听消息OslReadCircularQ(OslReceiveMsgExtQ(mmi_qid, 1.4. 如何在 MMI 队列中写入消息当 NVRAM 接收到其他消息时:OslWriteCircularQ(1.5. 如何从 L4C 接听消息注册一个消息回调函数SetProtocolEventHandler(FuncCB, msg_id);1.6. 如何向 L4C 发送消息2. 构建一个本地参数指针3. 将请求数据填充进本地参数指针
13、中。4. 给结构体 ilm_struct 赋值。5. 向 L4C 发送消息。消息信息 = 头信息 + 数据信息Local parameter Header info:#define LOCAL_PARA_HDR kal_uint8 ref_count; kal_uint16 msg_len;peer buffer parameter Header info :#define PEER_BUFF_HDR kal_uint16 pdu_len; kal_uint8 ref_count; kal_uint8 pb_resvered; kal_uint16 free_header_space; kal
14、_uint16 free_tail_space;2.7. 本地参数:(local parameter)Header info + Data info:例如:typedef struct LOCAL_PARA_HDRkal_uint8 volume_type;kal_uint8 volume_level; mmi_eq_set_volume_req_struct;2.8. 如何创建本地参数:(动态分配内存 )OslConstructDataPtr(sizeof(mmi_at_alarm_query_res_req_struct);2.9. 何时释放本地参数当 L4 接收到消息并处理完成后,会自动
15、释放参数。OslFreeDataPtr(sizeof(mmi_at_alarm_query_res_req_struct);Peer buffer parameter:Header info + Data infoEx: typedef struct PEER_BUFF_HDRvoid *ptr; mmi_example;mtk 学习开发归档 03如何创建 Peer buffer parameter:(动态分配内存)MMI 不使用 this buffer 和 L4 通信construct_peer_buff(pdu_len, header_len, tail_len, direction);3
16、.1. 何时释放 Peer buffer parameter当 L4 接收到消息并处理完成后,会自动释放参数。free_peer_buff(peer_buff);例程如下:Set a volume request:void SetVolumeLevelReq(volume_type_enum volume_type,U8 volume_level)MYQUEUE Message;mmi_eq_set_volume_req_struct *setVolumeLevelReq;Message.oslMsgId = MSG_ID_MMI_EQ_SET_VOLUME_REQ;/Message ID,
17、reference the l4a.h filesetVolumeLevelReq = OslConstructDataPtr(sizeof(mmi_eq_set_volume_req_struct);/Create local parameter buffersetVolumeLevelReq-volume_type = volume_type;setVolumeLevelReq-volume_level = volume_level;Message.oslDataPtr = (oslParaType *)setVolumeLevelReq; /Local parameter bufferM
18、essage.oslPeerBuffPtr= NULL; /Peer parameter bufferMessage.oslSrcId=MOD_MMI; /Send from Source moduleMessage.oslDestId=MOD_L4C; /Send to destination moduleOslMsgSendExtQueue( /Send to L4 task每个功能的具体实现(比如说播放音频 )都会定义 mmi_xxxxx_reg_sturct 形式结构体结构体组成:Header info + Data info:例如(请求播放音频):typedef structLOCA
19、L_PARA_HDR /头信息(Header info)kal_uint8 sound_id;kal_uint8 style; /* audio_play_style_enum */ mmi_eq_play_audio_req_struct;3.2. 通信数据#define MYQUEUE ilm_structtypedef struct ilm_struct oslModuleType oslSrcId; / Source module ID.oslModuleType oslDestId; / Destination module ID.oslMsgType oslSapId; / ser
20、vice access point.oslMsgType oslMsgId; / message name ID.oslParaType *oslDataPtr; /local parameter bufferoslPeerParaPtr *oslPeerBuffPtr; /peer buffer pointer ilm_struct;3.3. 示例代码MYQUEUE Message;mmi_eq_play_audio_req_struct *audioPlayReq;/create local parameter bufferaudioPlayReq = OslConstructDataPt
21、r(sizeof(mmi_eq_play_audio_req_struct);audioPlayReq-sound_id = (U8) soundId;audioPlayReq-style = 2; /* style; */audioPlayReq-identifier = (U16) soundId;Message.oslMsgId = PRT_EQ_PLAY_AUDIO_REQ; /message id,reference the l4a.hMessage.oslDataPtr = (oslParaType*) audioPlayReq; /local parameter bufferMe
22、ssage.oslPeerBuffPtr = NULL; /Peer parameter bufferMessage.oslSrcId = MOD_MMI; /Send from Source moduleMessage.oslDestId = MOD_L4C; /Send to destination moduleOslMsgSendExtQueue( /Send to L4 task1. Network simulator 分析MMI : Man machine InterfacePMS : Pixtel MMI SimulatorNWS : Network Simulator (MMIN
23、WSimulator)DTD : Document Type DefinitionXML : Extensible Markup Language1.1. 模拟协议栈1.1.1. PMSNWSXML(Sends Automatic andManual Messages)PluginsData FileIcoming messagesOutgoing messagesAsvc EventsVia File I/OCallsReturn dataMessage Flow1.1.2. NetWork Simulator 任务1. 联系 NWS 和 PMS,模拟 MMI 和 协议栈之间的通讯2. 在数
24、据文件中存储数据来模拟 Flash 中的数据存储1.1.3. NWS 同 PMS 通讯方式NWS 同 PMS 之间通过三种方式通信1. 接收从 PMS 发送给 NWS 的 incoming messages 例如,拨号请求2. 对 incoming message 从 NWS 发送 outgoing message 到 PMS 例如,获得电话薄入口请求3. 从 NWS 发送异步消息到 PMS 例如,Boot Up 等。资源的添加菜单资源1. 菜单 ID : 如 ORGANIZER_CALENDER_MENU,这个即是一个菜单的 id 也就是名字,但要把这个菜单加入到某个父菜单之下,则须指定其父
25、菜单,方式可以参照:ORGANIZER_CALENDER_MENU 这个菜单的方法,在 res_mainmenu.c 里,ADD_APPLICATION_MENUITEM(MAIN_MENU_ORGANIZER_MENUID,IDLE_SCREEN_MENU_ID,ORG_ENUM_TOTAL,#if defined(_MMI_CALENDAR_)ORGANIZER_CALENDER_MENU,#endif#if defined(_MMI_TODOLIST_)ORGANIZER_TODOLIST_MENU,#endifORGANIZER_ALARM_MENU,#if defined (_MMI
26、_WORLD_CLOCK_)ORGANIZER_WORLDCLOCK_MENU,#endif#ifdef _MMI_MESSAGES_CLUB_MAIN_MENU_SHORTCUTS_MENUID,#endif#ifdef _SLT_LONG_DISTANCE_DDD_MENU_LONG_DISTANCE_DDD,#endifSHOW,MOVEABLEACROSSPARENT,DISP_LIST,MAIN_MENU_ORGANIZER_TEXT,MAIN_MENU_ORGANIZER_ICON);这个语句说明菜单 ORGANIZER_CALENDER_MENU 是菜单MAIN_MENU_ORG
27、ANIZER_MENUID 的子菜单。而在 res_organizer.c 里,ADD_APPLICATION_MENUITEM(ORGANIZER_CALENDER_MENU,MAIN_MENU_ORGANIZER_MENUID,3,MENU_GOTO_TASK_CAL,MENU_ID_CLNDR_JUMP_TO_DATE,MENU_CAL_TYPE,SHOW,MOVEABLETOSHORTCUT,DISP_LIST,ORGANIZER_MENU_CALENDER_STRINGID,ORGANIZER_MENU_CALENDER_IMAGEID);这个语句则声明了 ORGANIZER_CAL
28、ENDER_MENU 菜单所拥有的子菜单。关于宏 ADD_APPLICATION_STRING2()、ADD_APPLICATION_MENUITEM() 可以参考文件 Writing Applications Using Pixtel MMI Platform.pdf更深入的了解可以查看文件夹 DocumentMMI Design DocumentsPixtel 下的文件。总结:1、在 GlobalMenuItems.h 中添加一个菜单 ID例如:#ifdef SWITCHMENU_ID_FIRST_APP,#endifextraResDefs.h:STR_ID_FIRST_APP/定义字符
29、资源 ID 2、在对应的 res_XXX.c(如 Res_extra.c)文件中添加菜单资源所用函数为:ADD_APPLICATION_MENUITEM()参数为:第一个参数: 菜单本身的 ID第二个参数: 父菜单的 ID(ref_list.txt 中找)第三个参数: 子菜单的个数(如果子菜单数不位 0,应把子菜单 ID 依次列出,形如: ID1,ID2,.)第四个参数:SHOW 或隐藏第五个参数:菜单的 flags 可以 Copy第六个参数:菜单的风格 DISP_LIST 等第七个参数:字符串资源的 ID第八个参数:图片资源的 ID3、搜索父菜单的 ID,在父菜单的资源的 ADD_APPLI
30、CATION_MENUTIEM()中的第三个参数加一,并且列举出菜单的 ID4、添加字符串资源和图片资源,所用函数为:ADD_APPLICATION_STRING2()和ADD_APPLICATION_IMAGE2()参数一:资源的 ID参数二:默认显示的字符(一般为英文解释)参数三:描述5、多国语言:打开.plutommiCustomerCustResourcePLUTO_MMI 下的 ref_lis.text在末尾添加 形如:STR_ID_VRSI_DELETE_QUESTIONVRSI 20 Delete? Delete? 刪除? 删除?具体为:字符串 ID 所属程序 长度 描述 英文
31、繁体中文 简体中文它们之间用 Tab 键隔开,如果不确定 可以用 Excel 打开二.异同(ADD_APPLICATION_MENUITEM()和 ADD_APPLICATION_MENUITEM2())MTK 添加菜单有两个宏ADD_APPLICATION_MENUITEM()ADD_APPLICATION_MENUITEM2()他们之间有什么区别呢?首先是结构不同:ADD_APPLICATION_MENUITEM 需要要指明子菜单个数。例如下面第三个参数为子菜单个数ADD_APPLICATION_MENUITEM(MENU_BARRING_OPTION,0, 3,MENU_BARRING_
32、ACTIVATE,MENU_BARRING_DEACTIVATE,MENU_BARRING_QUERY, SHOW, NONMOVEABLE, DISP_LIST, STR_MENU_BARRING_OPTION, NULL);ADD_APPLICATION_MENUITEM2 不需要指明子菜单个数,子菜单结尾处加一个MENU_ITEM_END 标示子菜单项结束。例如ADD_APPLICATION_MENUITEM2(MENU_ID_UCM_INCALL_OPTION_NEW_CALL, MENU_ID_UCM_INCALL_OPTION,MENU_ID_UCM_INCALL_OPTION_N
33、EW_CALL_VOICE,#ifdef _MMI_VOIP_MENU_ID_UCM_INCALL_OPTION_NEW_CALL_VOIP, #endif /* _MMI_VOIP_ */MENU_ITEM_END,SHOW, MOVEABLEWITHINPARENT, DISP_LIST, STR_ID_UCM_NEW_CALL,0); 用法上需要注意什么呢?ADD_APPLICATION_MENUITEM() 任何地方都可以使用。一般用于固定个数不变的菜单。还有叶子菜单(即最底层菜单) 。ADD_APPLICATION_MENUITEM2() 必须要包含子菜单,不能用于叶子菜单。它最大的
34、一个作用是用于动态的菜单。我们知道 MTK 有个 features_switch 里面有好多宏开关,根据宏开关变化 一些菜单也需要改变,这就用到了 ADD_APPLICATION_MENUITEM2(), 因为它没有规定子菜单的个数。三.添加 string 资源:首先给该字符串起一个名字,即 ID:如 STR_GLOBAL_OK,这个即是一个字串的 id 也就是名字,而这个字串的具体内容(比如 STR_GLOBAL_OK 的内容是“Ok”) ,可以用下面的语句来添加:ADD_APPLICATION_STRING2(STR_GLOBAL_OK, “Ok“,“Global String- OK“);如果有对应的中文字符,则应在 ref_list.txt 中按照固定的格式添加中文字串。如: