嵌入式技术论坛
直播中

疯壳科技

7年用户 1201经验值
擅长:嵌入式技术
私信 关注

疯壳-MTK智能穿戴入门篇-编程之资源

`
目录
一、MTK开发环境搭建        3
二、MTK平台框架        6
三、MTK编译指令        11
四、MTK编程入门        11
五、资源        12
六、新增APP        22
MTK编程——资源
        MTK的资源分为很多种,有图片资源、铃声资源、字符串资源、屏幕资源、菜单资源、定时器资源、nvram 资源,消息接收器等。所有的资源都定义在 .res 文件中,使用 XML 语句书写,所有的资源在 res 文件中都是用包含,而 APP_NAME 需要在mmi_pluto_res_range_def.h 文件中设置各个资源的个数。
例如:
1 (1).png
1MMI_RES_DECLARE(APP_MAINMENU, 300, ".MMIMainMenuMainMenuRes")
        APP_MAINMENU定义在MainMenuRes.res 文件中,包含所有的资源。300 是指资源的最大个数,这里并不是所有资源相加的,而是图片、字串等资源各自可以添加300个。".MMIMainMenuMainMenuRes"表示APP_MAINMENU 所在资源文件的目录。
2#define MAIN_MENU_BASE                       ((U16) GET_RESOURCE_BASE(APP_MAINMENU))
        资源ID 的最小取值,所有资源ID 的数字大于MAIN_MENU_BASE
3#define MAIN_MENU_BASE_MAX                   ((U16) GET_RESOURCE_MAX(APP_MAINMENU))
        资源ID 的最大取值,所有资源ID 的数字小于MAIN_MENU_BASE,实际上MAIN_MENU_BASE + 300 = MAIN_MENU_BASE_MAX
        添加完资源之后,都需要使用 make resgenmake  FengKe2502C_11C GPRS  resgen)编译资源,生成二进制。如果在真机上调试,在make resgen之后还需要使用 make r mmiresource 重新编译资源模块,或者直接使用 make u mmiresource 编译,在模拟器上调试可以不用编译mmiresource
        资源编译之后,都会在plutommiCustomerCustomerInc目录下生成一个mmi_rp_app_name_def.h 的文件,比如上面的app_name APP_MAINMENU,则生成的文件名为mmi_rp_app_mainmenu_def.h 。在该文件中,所有同类型的资源都会生成一个enum枚举,枚举命名格式为mmi_rp_app_name_style_enumstyle为资源类型,比如mmi_rp_app_mainmenu_str_enum 则为所有的字串资源ID。如果res文件中的ID,在这个文件里能够找到,说明资源生成成功。习惯上所有资源ID名称都用大写。

屏幕资源
         MTK 设备上,每一个屏幕都对应唯一一个屏幕ID。屏幕之间的相互切换,屏幕历史堆栈管理,都是通过屏幕 ID 进行的。屏幕资源的添加方法使用如下语句:
或者
        屏幕ID资源的命名方式,习惯上以 SCR_开头,比如 ,或者以GRP_ 开头。比如 。通常情况下,以SCR_开头的资源一般作为实际的单个屏幕,而以GRP_开头的资源都用于屏幕组(group),一个GRP屏幕组下面,可以包含多个SCR屏幕,当你关闭一个GRP屏幕组时,那么其下的所有SCR屏幕都被关闭了。实际上SCR GRP 都是同类型的资源,在使用的时候反过来也没有问题,但我们反对这么做,因为从命名上来看会导致歧义,减弱代码的可读性和可维护性。在MTK中所有的屏幕是呈一个树形结构,(见下图)

以下介绍几个常用的屏幕相关接口:
1、 MMI_ID mmi_frm_group_create (MMI_ID parent_id, MMI_ID group_id, mmi_proc_func proc, void *user_data)
函数功能:创建一个屏幕组。
参数parent_id:屏幕组的父类,通常情况下可以填GRP_ID_ROOT
参数group_id:是要创建的屏幕组ID
参数proc:屏幕组的消息处理函数
参数user_data:用户需要传递的数据,通常情况下用 NULL

2、 MMI_BOOL mmi_frm_scrn_enter (MMI_ID parent_id, MMI_ID scrn_id, FuncPtr exit_proc, FuncPtr entry_proc, mmi_frm_scrn_type_enum scrn_type)
函数功能:进入一个屏幕。
参数parent_id:屏幕的父类,可以是我们自定义的屏幕组,也可以填GRP_ID_ROOT
参数scrn_id:屏幕ID
参数exit_proc:退出屏幕时的处理函数,一般用于释放资源。如果没有退出函数,则填NULL
参数entry_proc:屏幕的入口函数,当屏幕从历史堆栈中弹出时,会执行这个函数。
参数scrn_type:屏幕类型,一般常用的是MMI_FRM_FULL_SCRN MMI_FRM_UNKNOW_SCRN
3、 mmi_ret mmi_frm_group_close (MMI_ID group_id)
函数功能:关闭屏幕组group_id
4、 mmi_ret mmi_frm_scrn_close (MMI_ID parent_id, MMI_ID scrn_id)
函数功能:关闭屏幕组parent_id下的scrn_id屏幕
5、 void mmi_frm_scrn_close_active_id (void)
函数功能:关闭当前处于激活状态的屏幕,即用户能够看到的屏幕。
6、 U16 GetActiveScreenId(void)
函数功能:获取当前处于激活状态的屏幕ID
1 (2).png

屏幕ID树状结构

        接下来我们自己定义一个屏幕ID,屏幕组ID暂时不讲解。在Idle.res文件中找到,在后面添加一句,代码如下:
1 (3).png
        然后用 make resgen 编译,编译完成之后打开mmi_rp_app_idle_def.h文件,在mmi_rp_app_idle_scr_enum枚举中看是否能找到SCR_ID_MY_MTK_FUNC,如果能找到说明资源添加成功了。接下来我们将mmi_my_mtk_func函数作为一个屏幕入口函数,让它进入一个屏幕,同样打印出"Hello MTK !",并注册右软键功能关闭该屏幕,然后添加一个屏幕退出函数mmi_my_mtk_func_exit,在退出该屏幕时,我们打印"Exit Hello MTK !",具体代码如下:
1 (4).png

        VS2008 中编译,运行模拟器。我们点击左软件的时候,屏幕上依旧会显示"Hello MTK !",当我们点击右软键的时候,屏幕上会显示"Exit Hello MTK !",但是会闪一下就消失,因为先执行退出函数,然后会立即执行idle界面的入口函数,绘制idle界面的内容,从而把"Exit Hello MTK !"覆盖掉了。读者可自己使用断点,查看代码执行流程。

字符资源
        在上一个例子中,我们显示"Hello MTK !"直接使用的是字符常量,这样的方式在单一语言下是没有问题的,但如果系统包含多国语言,比如从英文切换到中文,如何把"Hello MTK !"直接显示成中文呢?这里就要用到字符资源,字符资源全部添加在plutommiCustomerCustResourcePLUTO_MMI
ef_list.txt 文件中,里面包含约80种语言字符,我们只要输入对应语言的字符,那么字符显示成何种语言就会随系统的语言设置而变化。MTK提供了一个专用于修改字符资源的工具——plutommiCustomer STMTView.exe。接下来我们把"Hello MTK !"添加成字符资源,然后通过GetString函数接口提取字符串。添加字符资源的语句格式为:
           "default string"
        字符资源ID命名通常以“STR_”开头,这两种方法的区别在于前者设置了默认值,如果STR_NAMEref_list.txt不存在的话,那它在任何语言下都会显示"default string"(注意:此处添加的默认值只能是英文字符)。而后者没有默认值,如果STR_NAMEref_list.txt不存在的话,请读者自己测试会显示什么内容。
        我们采用设置默认值的方式添加字符资源,在idle.res文件中添加字符资源ID——STR_ID_HELLO_MTK,代码如下:
1 (5).png
        然后在plutommiCustomerCustResourceFengKe2502C_11C_MMIMMI_features_switchFengKe2502C_11C.h文件中找到宏开关CFG_MMI_LANG_SM_CHINESE把后面的(__OFF__)改为(__ON__)这里是让系统支持简体中文,为方便我们验证字符资源的多国语言翻译问题。接下来还要为系统添加字库,在FengKe2502C_11C_GPRS.mak文件中设置FONT_ENGINE = FONT_ENGINE_ETRUMP,使用矢量字库。
        打开plutommiCustomerSTMTView.exe,点击File>Open STMT会显示两个表格栏,随便选择一个,单击点击红色标注的图标 1 (6).png ,在弹出的文件选择对话框中,选择plutommiCustomerCustResourcePLUTO_MMI
ef_list.txt然后打开,出现如下界面:
1 (7).png
        在打开文件的一栏中单击鼠标右键,选择Insert new row。如下图所示填充弹出框:
1 (8).png

1Enum value:字符资源的枚举ID,必须跟.res文件中添加的资源ID一一对应,否则资源无法加载。
2Mode name:字符资源所在的功能模块,这个可以使用默认的值,仅作为描述。
3Region ID:这个也仅是描述作用,可以手动输入,也可以点击旁边的按钮选择,也可以不填。
4Description:这个也仅是描述作业,可以描述字符ID的用途。
5Default value:字符资源ID的默认值,在任何语言下都是会默认使用这个值。
下面的复选框打勾,把资源ID添加到文件的最后一行,点击OK。在新增的一行,对应 Si_Chinese列把"Hello MTK !"改成“你好,MTK !”,添加效果如图:
1 (9).png
mmi_my_mtk_func 函数中把L"Hello MTK !" 改成GetString(STR_ID_HELLO_MTK),暂且把mmi_my_mtk_func_exit函数中的代码清空,具体代码如下:
1 (10).png
        上面我们修改了MMI_features_switchFengKe2502C_11C.hFengKe2502C_11C_GPRS.mak这两个文件,只要修改了这两个文件的任意一个,都必须执行make new编译,再用make gen_modis重新生成模拟器。如果这两个文件没有修改,则make resgen就可以了。编译完后打开plutommiCustomerResGeneratordebugstring_resource_usage.txt 文件看是否能找到STR_ID_HELLO_MTK,系统中所有的字符资源ID编译成功之后都可以在这个文件中找到,如果找不到则说明资源添加失败。字符资源编出来之后就是UCS2编码。在VS2008中运行模拟器,点击 KEY_LSK,运行效果如下:

        系统默认是英语环境,所以依旧显示"hello MTK !",接下来我们把系统切换成中文。打开GeneralSettingSrv.c文件,在srv_setting_get_language函数中把return data;改为return 1;再次运行模拟器,点击KEY_LSK,运行效果如下:
1 (12).png

        字符资源的最大优势,就是可以支持多国语言,而对于程序员来说,只有一个资源ID。在调用GetString时,它会根据系统环境的语言设置,获取对应的字符串指针。

图片资源
        MTK中显示的图片有三种,一是通过资源加载的,二是显示磁盘中的文件,三是直接把图片转成二进制数组显示,这种方式常用于SP游戏或应用开发。此处我们只讲图片资源。图片资源跟字符资源一样,也是添加在 .res文件中,添加图片资源的语句格式为:

            CUST_IMG_PATH"image_filepath\image_filename"

        图片资源ID命名通常以“IMG_”开头,所有的图片资源都放在plutommiCustomerImage文件夹中,在这个文件夹中包含不同屏幕尺寸的图片资源,每个屏幕尺寸对于的文件夹下都有一个image.zip压缩包中,系统中的图片资源就放在这个压缩包中,我们添加的图片也要放到压缩包对应的目录中,在编译资源的时候,系统会将其解压成MainLCD目录。CUST_IMG_PATH是一个宏,定义在plutommiCustomerCustResourcePLUTO_MMI CustResDefPLUTO.h文件中,它指向image.zip所在的目录,比如当前屏幕尺寸为240X320(屏幕尺寸的配置在FengKe2502C_11C_GPRS.mak文件中查看MAIN_LCD_SIZE宏定义),则CUST_IMG_PATH 定义指向plutommiCustomerImagesPLUTO240x320目录,系统中定义的代码如下:
1 (13).png
        image_filepath是相对于MainLCD的目录,image_filename就是图片的文件名,包含后缀名。图片资源的格式可以是bmppngjpggif还有MTK系统特定的一些图片格式。系统中添加成功的图片资源,其资源ID都可以在文件plutommiCustomerResGeneratordebug image_resource_usage.txt中找到。如果资源加载失败,则资源ID会被添加到相同目录的image_load_fail.txt文件中,这种情况通常都是图片的目录错误,或者image.zip中没有这个图片文件。
        接下来我们添加一个图片资源,plutommiCustomerImagesPLUTO240x320MainLCDIdleScreenWallpaper目录下,随便找一张图片,或者自己随便找一张图片放到image.zip对应的目录中。这里我就使用WALL01.jpg来做测试。在idle.res文件中添加一个资源ID——IMG_ID_HELLO_MTK,并加载WALL01.jpg图片,代码如下: 1 (14).png
        然后使用 make resgen 编译,编译完成之后在image_resource_usage.txt看是否能找到IMG_ID_HELLO_MTK,如果能找到,说明资源加载成功。接下来在mmi_my_mtk_func函数中调用gdi_image_draw_id接口把图片显示出来。因图片是黑色,所以我们把字符颜色改为白色(UI_COLOR_WHITE),代码如下:
1 (15).png
运行模拟器,效果如图:
1 (16).png

显示图片的资源有:
1、 gdi_image_draw_id(OFFSET_X,OFFSET_Y,IMAGE_ID)   
函数功能:这是一个宏函数,根据图片ID在屏幕上显示图片
OFFSET_X:图片的显示的X坐标。
OFFSET_Y:图片的显示的Y坐标。
IMAGE_ID:图片资源ID
2、 gdi_image_draw_resized_id(OFFSET_X,OFFSET_Y,RESIZED_WIDTH,RESIZED_HEIGHT,IMAGE_ID)
函数功能:这个函数可以实现图片的缩放,不管图片的尺寸是多少,都显示成指定的大小。
OFFSET_X:图片的显示的X坐标。
OFFSET_Y:图片的显示的Y坐标。
RESIZED_WIDTH:图片显示的宽度,如果大于这个宽度则缩小,如果小于这个宽度则放大。
RESIZED_HEIGHT:图片显示的高度,同RESIZED_WIDTH一样缩放图片。
IMAGE_ID:图片资源ID
3、 gdi_image_draw(OFFSET_X,OFFSET_Y,IMAGE_PTR)
函数功能:这个函数的执行效果跟gdi_image_draw_id函数是一样的,只不过参数需传入一个图片的数组
OFFSET_X:图片的显示的X坐标。
OFFSET_Y:图片的显示的Y坐标。
IMAGE_PTR :图片二进制数组,通常可通过GetImage(IMAGE_ID)获取。

        另外,图片资源还有gif动画,动画资源的添加方式跟图片资源是一样的,只不过显示的函数接口有点区别,动画的接口包含在gdi_include.h文件中,通常是以gdi_anim_ 开头的函数,比如gdi_anim_draw_id,关于动画的使用本章暂时不做过多的讲解,有兴趣的读者可以自己看代码学习。

菜单资源
菜单的添加方法比图片和字符稍微复杂些,格式有如下三种:
1        菜单中包含子菜单。
        < MENU        ……[item  value]…… >
                MENU_ITEM_ID
                …………………………
        
        如果不包含子菜单则可以写成:
        < MENU        ……[item  value]…… /> < MENU        ……[item  value]…… > MENU >
2、菜单中不包含子菜单
        
3、菜单作为主菜单
        
        此处的MENU_ID 必须是通过第一种方式已经加载成功的菜单资源ID

        以上三种格式的省略号(……)省略了一些属性值,有些属性是可有可无的,在后面通过代码来讲解。在上一个例子中,我们直接把mmi_my_mtk_func放在idle界面的,通过注册按键的方式执行。在这一节中我们把mmi_my_mtk_func 放到菜单中,作为菜单的功能入口函数。
        首先我们把idlecommon.c文件中mmi_idle_set_handler函数里最后一行SetKeyHandler(mmi_my_mtk_func, KEY_LSK, KEY_EVENT_UP);去掉。添加一个mmi_highlight_my_mtk 函数,作为菜单的高亮处理函数,并注册左右软键功能,代码如下:
1 (17).png

然后在MainMenuRes.res 文件中添加一个菜单MENU_MY_MTK_ID ,并把它放到MAIN_MENU_SETTINGS_MENUID设置菜单下面,代码如下:
1 (18).png
idlecommon.c 文件中mmi_idle_set_handler函数最后一行,把SetKeyHandler(mmi_my_mtk_func, KEY_LSK, KEY_EVENT_UP);改为SetKeyHandler(EntryScrSettingMenu, KEY_LSK, KEY_EVENT_UP);强制进入设置菜单选项。执行 make  resgen 再到 VS2008 中重新编译并运行模拟器,点击LSK,进入“设置”菜单,在设置菜单界面就可以看到我们自己添加的菜单了“你好,MTK !”,再点击确定,就执行了我们之前添加的函数mmi_my_mtk_func。如下图所示:
1 (19).png 1 (20).png
1.
type="APP_MAIN":描述菜单的类型。取值可选 APP_SUBOption
str="STR_ID_HELLO_MTK":菜单名称的字符串资源ID,如上图设置菜单列表界面显示的你好,MTK !”
img="IMG_GLOBAL_OK":菜单的图标资源ID,显示在菜单的最坐标,但这里没有显示,而是用编号代替,如上图编号1。如果显示菜单自己的图标,需要修改代码,打开相关功能宏。
highlight="mmi_highlight_my_mtk":菜单被选中的时候,会执行该处理函数。

2. MENU_MY_MTK_ID
在其他菜单下面添加子菜单。此处还有另一种写法,可用下面的语句代替,并删除上面第1条语句。最终执行的结果是一样的,请读者自己尝试。

        菜单添加成功可以在plutommiCustomerCustResourceCustMenuTree_Out.c文件中找到对应的ID,这个文件包含系统中所有菜单ID 的依赖关系,菜单跟屏幕一样也是呈树形结构,IDLE_SCREEN_MENU_ID是树的根,除此之外,所有的菜单ID在该文件中至少出现两次。
        如果添加菜单时有highlight属性,则在plutommiFrameworkEventHandlingEventsIncmmi_menu_handlers.h文件中可以查看到IDhighlight函数的对应关系。
铃声资源
        铃声资源的添加方式跟图片资源相似,系统中所有的铃声文件都包含在plutommiCustomerAudioPLUTO audio.zip压缩包中,编译资源时会被解压,所以我们添加的铃声文件也要放到这个压缩包中。添加铃声资源的格式为:
说明:
        id="AUD_ID_NAME":资源ID 的名称。
        flag="MULTIBIN":描述资源的属性,这个属性可有可无。
        CUST_ADO_PATH:宏定义,指向plutommiCustomerAudioPLUTO目录
        file_pathaudio.zip压缩包中,铃声文件所在的目录。
        file_name:铃声文件名。格式可为mp3wavmidimy 等。

        系统中大多数铃声资源都在情景模式中,见ProfilesSrv.res文件。铃声资源编译成功后,可以在plutommiCustomerResGeneratordebugaudio_resource_usage.txt文件中找到ID以及与其对应的铃声文件。铃声资源的播放,可以用get_audio 获取铃声资源的数组,然后再用mdi_audio_play_string_with_vol_path函数播放。此处不做代码测试,留给读者自己完成。
nvram 资源
        MTK 设备有些数据在关机之后也要保存。实现这种功能的方法有两种,一种方法是存储到磁盘文件中,另一种方法就是我们本节要讲的nvram(简称NV)。而nvram也分为两种,一种可以存储复合数据类型,比如结构体;而另一种只能存储数值类型,比如byteshortdouble,我们用的最多的是byteshort。存储数值类型的NV就是通过资源的方式添加,添加NV资源的格式为:
        
         [value]
         description
               
   
说明:
        type=" type"type 的取值有 byteshortdoublebyte只能存一个字节,short能存两个字节,double可以存8个字节,一般用的很少,如果存储的数据量较大,则作为复合数据类型存储。
        id="NVRAM_NAME" : NVRAM 的资源IDNV 的读写都是通过ID进行。
        restore_flag="TRUE/FALSE"TRUE恢复出厂设置时重置该NV的值为默认值
         [value] NV的默认值,typebyte,取值最大为[0xFF]short最大为[0xFF,0xFF],左侧为高为,右侧为低位;double最大为[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],同样是左侧高位,右侧低位。比如typeshort,存储value300,转换成十六进制为[0x01,0x2C]
         description NV的描述,相当于注释。这个属性可以缺省。
        :描述NV的取值范围。这个属性也可以缺省。

        比如,系统中保存背光亮度和背光时间的NV,在gpiosrv.res文件中定义如下:
1 (21).png
NV资源的读写通常用以下两个函数:
1、 S32 ReadValue(U16 nDataItemId, void *pBuffer, U8 nDataType, S16 *pError)
函数功能:读取NV中存储的值。
nDataItemId:NV的资源ID。
pBuffer:保存NV中读取到的数值。
nDataType:NV 的类型,取值有DS_BYTE、DS_SHORT、DS_DOUBLE,分别对应资源中的byteshortdouble类型
pError;这个参数在函数实现中暂时并没有实际的作用。

例句:ReadValue(NVRAM_BYTE_BL_SETTING_HFTIME, &hftime, DS_SHORT, &error);

2、 S32 WriteValue(U16 nDataItemId, void *pBuffer, U8 nDataType, S16 *pError)
函数功能:把pBuffer中的数值写入NV中。
nDataItemId:NV的资源ID。
pBuffer:需要写入NV中的数值。
nDataType:NV 的类型,取值有DS_BYTE、DS_SHORT、DS_DOUBLE,分别对应资源中的byteshortdouble类型
pError;这个参数在函数实现中暂时并没有实际的作用。

例句:WriteValue(NVRAM_BYTE_BL_SETTING_HFTIME, &hftime, DS_SHORT, &error);

        本节只简单的介绍NV资源的添加,以及读写方式,在后面的章节中会有单独一章详细讲解NVRAM,包括存储简单数据类型和复合数据类型。
定时器资源
        定时器的作用就是延后执行某一个操作,也可以每隔一段时间就执行一次。定时器ID 的添加方式有两种,一种是在TimerEvents.h文件中的MMI_TIMER_IDS枚举中添加,只要添加在KEY_TIMER_ID_NONE MAX_TIMERS之间就可以了,这种添加方式比较简单,通常驱动里面要用的定时器都添加在这个文件中。另一种方式是通过资源ID方式添加,这种方式添加的定时器跟第一种方式添加的定时器没有本质的区别,在使用上也是完全一模一样。MMI层用到的定时器两种添加方式都没有问题,但是强烈建议使用第二种,方便代码的模块化。
        定时器资源的添加方式为:
        TIMER_ID_NAME为自定义的定时器ID名称。定时器启动和停止的常用函数接口如下:
1、 void StartTimer(U16 timerid, U32 delay, FuncPtr funcPtr)
函数功能:启动定时器。
timerid:定时器的资源ID。
delay:定时器执行的时间间隔。
funcPtr:定时器执行的函数。

2、 void StopTimer(U16 timerid)
函数功能:停止定时器。
timerid:定时器的资源ID。
消息接收器
        这个资源在实际开发中用的比较少,一般都是系统自带的。我们只需要了解一下就可以了,消息接收器的定义方式如下:
               
说明:
        id=" RECEIVER _ID_NAME":为消息ID
        proc="reveiver_func":消息ID 的处理函数。这个函数一般由系统调用。

`
(5)MTK 编程之资源.pdf (1.2 MB)
(下载次数: 1, 2020-9-29 15:52 上传)
1 (20).png 1 (11).png

更多回帖

×
20
完善资料,
赚取积分