删除多余的被占用的串口

删除被占用的串口

点击“开始”,选择“运行”,之后输入cmd,回车。

在对话框内输入”set devmgr_show_nonpresent_devices=1”,回车。 接着输入“start devmgmt.msc”,回车。

打开设备管理器,选择“查看”菜单中的“显示隐藏设备”,展开USB相关驱动,选择不需要的卸载即可。

不要试图卸载COM1,COM2

 

第二篇:串口使用

1、串口的初始化

在MTK平台上,串口的操作和常见的操作系统不太一样,串口句柄并不是以文件形式的出现,而是有点类似单片机的做法,即每个串口有固定的编号,串口的初始化不需要有类似Windows/Unix等打开设备文件的操作(实际上是有UART_Open这个函数的,不过我们没有用到,大概是底层硬件初始化会用到,这里我们简单的理解成不需要Open就好了),下面我们对照实际的初始化代码逐句讲解初始化所需要做的事情,如下所示:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 我们要用到的串口, uart_port1是枚举型数值,usb串口的编号

#define HELLO_WORLD_UART_PORT uart_port1 // 手机接USB下载线的地方

// 定义我们的应用所属系统的哪一个模块

// 这里是MMI模块,实际上我更愿意称MMI为一个子系统,将我们的应用称为模块

#define MOD_HELLO_WORLD MOD_MMI

// 数据接收Buffer大小

#define MAX_ECHO_PACKET_LEN 128

// 睡眠模式句柄

static kal_uint8 ghSleepMode;

// 我们要用到的串口之前的占用者

static module_type gnOrigUartOwner;

static kal_bool gbUartInitialized = KAL_FALSE;

static void init_uart(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

if(gbUartInitialized)

{

return;

}

ghSleepMode = L1SM_GetHandle();

// 禁止休眠,休眠后串口收发会有问题

// 问题:如何做到串口唤醒? FIXME

L1SM_SleepDisable(ghSleepMode);

// 记录我们要用的串口的当前占有者

gnOrigUartOwner = UART_GetOwnerID(HELLO_WORLD_UART_PORT);

// 下面我们申明要占用这个串口了

UART_SetOwner(HELLO_WORLD_UART_PORT, MOD_HELLO_WORLD);

// 以上对串口占用的申明,我理解更多是一种编程者之间的约定 // 当发现串口的占用者不是本程序所属模块时,说明我们申明占用之后

// 又有其他模块申明占用同一个串口,此时如果收到数据应不予处理 // 当然,也有可能同一模块的其他程序申明占用同一串口

// 这需要在设计应用时统一协调,避免数据发生混乱

// 设置波特率,缺省的起停位和校验为:8,n,1,即8个数据位,1个停止位,无校验

UART_SetBaudRate(HELLO_WORLD_UART_PORT, UART_BAUD_115200, MOD_HELLO_WORLD);

// 其他串口设定(如起停位、校验等)使用函数 UART_ReadDCBConfig 和 UART_SetDCBConfig

// 详细参数见结构体 UARTDCBStruct

// 注册一个事件钩子函数,当串口(任何)有数据到达时,我们的钩子函数将被调用

// 注意,同一种事件同时只能注册一个钩子函数,因此:

// 如果在我们的程序处理串口的同时还有其他程序要读取和处理(任何)串口数据,

// 就必须由当前的钩子函数代为处理

// 实际上我觉得系统底层可以改一下,改成Windows钩子的方式,可以挂多个,能够依次调用或跳过

SetProtocolEventHandler(mmi_HelloWorld_uart_readyToRead_ind_handler, MSG_ID_UART_READY_TO_READ_IND);

gbUartInitialized = KAL_TRUE;

#endif

}

2、从串口读数据

这里有两个相关的函数,第一个是上面初始化部分提到的钩子函数mmi_HelloWorld_uart_readyToRead_ind_handler,另外一个是读函数,函数体如下所示:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void mmi_HelloWorld_uart_readyToRead_ind_handler(void *msg) {

#ifdef __MMI_HELLOWORLD_ENABLED__

uart_ready_to_read_ind_struct* uart_rtr_ind =

(uart_ready_to_read_ind_struct*)msg;

// 检查一下端口以及所有者信息,不匹配的数据略过

// 注意,作为例子程序,我们只是查看和处理我们关心的数据

// 其他与此同时需要监听和处理串口数据的程序,须由相关的代码完成代理的工作

if( KAL_FALSE == gbUartEchoStarted ||

HELLO_WORLD_UART_PORT != uart_rtr_ind->port || MOD_HELLO_WORLD !=

UART_GetOwnerID(uart_rtr_ind->port) )

{

// 如果底层能做成钩子链,这里就可以调用钩子链的下一个钩子了

return;

}

gwLenUartBuffer = read_from_uart(gabyUartBuffer,

sizeof(gabyUartBuffer), HELLO_WORLD_UART_PORT, MOD_HELLO_WORLD);

// 呼叫数据处理部分

uart_echo_process();

#endif

}

static U16 read_from_uart(U8 *pbyBuf, U16 wLenMax, UART_PORT hPort, module_type hOwner)

{

U16 wLenAvail;

U16 wLenRead;

U16 wLenRet = 0;

U8 byStatus = 0;

#ifdef __MMI_HELLOWORLD_ENABLED__

// 收取数据,超出最大包长的数据将简单丢弃,这一层需要具体的应用协议做相应处理

while( (wLenAvail = UART_GetBytesAvail(hPort) > 0 && wLenRet < wLenMax) )

{

if (wLenAvail + wLenRet > wLenMax)

{

wLenAvail = wLenMax - wLenRet;

}

wLenRead = UART_GetBytes(hPort, (kal_uint8 *)(pbyBuf + wLenRet), (kal_uint16)wLenAvail, &byStatus, hOwner);

wLenRet += wLenRead;

}

// 读完之后,清除接收Buffer

UART_ClrRxBuffer(hPort, hOwner);

#endif

return wLenRet;

}

3、向串口写数据

static U8 write_to_uart(U8 *pbyBuf, U16 wLenBuf, UART_PORT hPort, module_type hOwner)

{

U16 wSent= 0;

U8 bRet = FALSE;

#ifdef __MMI_HELLOWORLD_ENABLED__

// 发送前清FIFO和Buffer,注意:这一步必须做,否则收发会有问题

UART_Purge(hPort, RX_BUF, hOwner); // 清除设备输入FIFO

UART_Purge(hPort, TX_BUF, hOwner); // 清除设备输出FIFO

UART_ClrTxBuffer(hPort, hOwner); // 清除发送Buffer

UART_ClrRxBuffer(hPort, hOwner); // 清除接收Buffer

wSent = UART_PutBytes(hPort, (kal_uint8 *)pbyBuf, (kal_uint16)wLenBuf, hOwner);

#endif

if (wSent == wLenBuf)

{

bRet = TRUE;

}

return bRet ;

}

4、关闭串口

关闭串口实际上是将相关的设置改动恢复到之前的状态,不需要有close的动作,如下所示:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void exit_uart()

{

#ifdef __MMI_HELLOWORLD_ENABLED__

if(gbUartInitialized)

{

// 恢复成原有的端口占用者

UART_SetOwner(HELLO_WORLD_UART_PORT, (kal_uint8) gnOrigUartOwner);

// 允许休眠

L1SM_SleepEnable(ghSleepMode);

gbUartInitialized = KAL_FALSE;

}

#endif

}

5、下载测试

Make remake一下->下载程序到手机->关闭下载工具->运行串口工具,打开USB下载线对应的串口,设定为115200,8N1->手机开机(此时下载线不要拔下,我们用的就是这个下载线测试的)->手机工具菜单->Hello World->手机左键启动串口Echo(启动后再按左键停止串口Echo)。

注1:串口的部分在仿真器上模拟不了,链接的时候也会提示找不到相关函数符号。

注2:在HelloWorld的串口Echo停止工作时我们也能偶尔看到串口会原样回显,这应该是其他程序在处理,不是我们的HelloWorld,我们的HelloWorld会将输入转成全大写再回显。

注3:使用手机的USB下载口当作串口时,要用USB下载线进行连接,同时要注意相关的工程设置为以下:

--------------

TST Config

< 无 >

< 115200 >

PS Config

< UART 1 >

< 115200 >

--------------

设置方法:

待机界面下(拨号)输入 *#3646633# (进入 工程模式)->设备->"Set UART"->"UART Setting"

程序运行后的电脑端截图如下:

我采用1ms定时发送“Hello, World!\r\n”, 每毫秒15字节的速度,接收比发送多,这是因为启动Echo时,我有送一个串“Hello World Uart Echo Example Started! \r\n”(40字节)过来,不过接收多出的部分应该不止10个字节

(1928380 – 1928370),应该是40个字节,数据似乎有部分丢失(刚好2个包, 15 * 2 = 30 = 40 - 10),应该是电脑端发送太快的原因(115200 / (8 + 1) / 1000 = 12.8字节/毫秒,小于15,而且还有数据处理和echo的时间),这样的响应速度算相当不错了。

6、完整的C程序

下面贴出比较完整的HelloWorld.c程序,供大家参考,由于时间的关系,开发心得暂时到此为止,感谢华禹公司及其兄弟公司的支持,感谢各位网友! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "stdC.h"

#include "MMI_Features.h" /* 编译开关会出现在这个由make update生成的文件里面 */

#include "L4Dr.h"

#include "L4Dr1.h"

#include "AllAppGprot.h"

#include "FrameworkStruct.h"

#include "GlobalConstants.h"

串口使用

#include "EventsGprot.h"

#include "mmiappfnptrs.h"

#include "HistoryGprot.h"

#include "HelloWorldProt.h"

#include "HelloWorldTypes.h"

#include "HelloWorldDefs.h"

#include "MainMenuDef.h"

#include "wgui_categories.h"

#include "Unicodexdcl.h"

#include "gui_data_types.h"

#include "Uart_sw.h"

// 我们要用到的串口, uart_port1是枚举型数值,usb串口的编号

#define HELLO_WORLD_UART_PORT uart_port1 // 手机接USB下载线的地方

// 定义我们的应用所属系统的哪一个模块

// 这里是MMI模块,实际上我更愿意称MMI为一个子系统,将我们的应用称为模块

#define MOD_HELLO_WORLD MOD_MMI

// 数据接收Buffer大小

#define MAX_ECHO_PACKET_LEN 128

// 外部函数申明,没有对应头文件,手动加吧

extern module_type UART_GetOwnerID(UART_PORT port);

extern void UART_ClrTxBuffer(UART_PORT port, module_type ownerid); extern void UART_ClrRxBuffer(UART_PORT port, module_type ownerid);

// 本程序内部使用的函数申明

static void init_uart(void);

static void mmi_HelloWorld_uart_readyToRead_ind_handler(void *msg); static U16 read_from_uart(U8 *pbyBuf, U16 wLenMax, UART_PORT hPort, module_type hOwner);

static U8 write_to_uart(U8 *pbyBuf, U16 wLenBuf, UART_PORT hPort, module_type hOwner);

static void exit_uart();

static void start_uart_echo(void);

static void uart_echo_process(void);

static void stop_uart_echo(void);

// 睡眠模式句柄

static kal_uint8 ghSleepMode;

// 我们要用到的串口之前的占用者

static module_type gnOrigUartOwner;

static kal_bool gbUartInitialized = KAL_FALSE;

static kal_bool gbUartEchoStarted = KAL_FALSE;

static U16 gwLenUartBuffer = 0;

static U8 gabyUartBuffer[MAX_ECHO_PACKET_LEN];

static void init_uart(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

if(gbUartInitialized)

{

return;

}

ghSleepMode = L1SM_GetHandle();

// 禁止休眠,休眠后串口收发会有问题

// 问题:如何做到串口唤醒? FIXME

L1SM_SleepDisable(ghSleepMode);

// 记录我们要用的串口的当前占有者

gnOrigUartOwner = UART_GetOwnerID(HELLO_WORLD_UART_PORT);

// 下面我们申明要占用这个串口了

UART_SetOwner(HELLO_WORLD_UART_PORT, MOD_HELLO_WORLD); // 以上对串口占用的申明,我理解更多是一种编程者之间的约定 // 当发现串口的占用者不是本程序所属模块时,说明我们申明占用之后

// 又有其他模块申明占用同一个串口,此时如果收到数据应不予处理 // 当然,也有可能同一模块的其他程序申明占用同一串口

// 这需要在设计应用时统一协调,避免数据发生混乱

// 设置波特率,缺省的起停位和校验为:8,n,1,即8个数据位,1个停止位,无校验

UART_SetBaudRate(HELLO_WORLD_UART_PORT, UART_BAUD_115200, MOD_HELLO_WORLD);

// 其他串口设定(如起停位、校验等)使用函数 UART_ReadDCBConfig 和 UART_SetDCBConfig

// 详细参数见结构体 UARTDCBStruct

// 注册一个事件钩子函数,当串口(任何)有数据到达时,我们的钩子函数将被调用

// 注意,同一种事件同时只能注册一个钩子函数,因此:

// 如果在我们的程序处理串口的同时还有其他程序要读取和处理(任何)串口数据,

// 就必须由当前的钩子函数代为处理

// 实际上我觉得系统底层可以改一下,改成Windows钩子的方式,可以挂多个,能够依次调用或跳过

SetProtocolEventHandler(mmi_HelloWorld_uart_readyToRead_ind_handler, MSG_ID_UART_READY_TO_READ_IND);

gbUartInitialized = KAL_TRUE;

#endif

}

static U16 read_from_uart(U8 *pbyBuf, U16 wLenMax, UART_PORT hPort, module_type hOwner)

{

U16 wLenAvail;

U16 wLenRead;

U16 wLenRet = 0;

U8 byStatus = 0;

#ifdef __MMI_HELLOWORLD_ENABLED__

// 收取数据,超出最大包长的数据将简单丢弃,这一层需要具体的应用协议做相应处理

while( (wLenAvail = UART_GetBytesAvail(hPort) > 0 && wLenRet < wLenMax) )

{

if (wLenAvail + wLenRet > wLenMax)

{

wLenAvail = wLenMax - wLenRet;

}

wLenRead = UART_GetBytes(hPort, (kal_uint8 *)(pbyBuf + wLenRet), (kal_uint16)wLenAvail, &byStatus, hOwner);

wLenRet += wLenRead;

}

// 读完之后,清除接收Buffer

UART_ClrRxBuffer(hPort, hOwner);

#endif

return wLenRet;

}

static U8 write_to_uart(U8 *pbyBuf, U16 wLenBuf, UART_PORT hPort, module_type hOwner)

{

U16 wSent= 0;

U8 bRet = FALSE;

#ifdef __MMI_HELLOWORLD_ENABLED__

// 发送前清FIFO和Buffer,注意:这一步必须做,否则收发会有问题 UART_Purge(hPort, RX_BUF, hOwner); // 清除设备输入FIFO UART_Purge(hPort, TX_BUF, hOwner); // 清除设备输出FIFO UART_ClrTxBuffer(hPort, hOwner); // 清除发送Buffer UART_ClrRxBuffer(hPort, hOwner); // 清除接收Buffer

wSent = UART_PutBytes(hPort, (kal_uint8 *)pbyBuf,

(kal_uint16)wLenBuf, hOwner);

#endif

if (wSent == wLenBuf)

{

bRet = TRUE;

}

return bRet ;

}

static void exit_uart()

{

#ifdef __MMI_HELLOWORLD_ENABLED__

if(gbUartInitialized)

{

// 恢复成原有的端口占用者

UART_SetOwner(HELLO_WORLD_UART_PORT, (kal_uint8) gnOrigUartOwner);

// 允许休眠

L1SM_SleepEnable(ghSleepMode);

gbUartInitialized = KAL_FALSE;

}

#endif

}

static void mmi_HelloWorld_uart_readyToRead_ind_handler(void *msg) {

#ifdef __MMI_HELLOWORLD_ENABLED__

uart_ready_to_read_ind_struct* uart_rtr_ind =

(uart_ready_to_read_ind_struct*)msg;

// 检查一下端口以及所有者信息,不匹配的数据略过

// 注意,作为例子程序,我们只是查看和处理我们关心的数据

// 其他与此同时需要监听和处理串口数据的程序,须由相关的代码完成代理的工作

if( KAL_FALSE == gbUartEchoStarted ||

HELLO_WORLD_UART_PORT != uart_rtr_ind->port || MOD_HELLO_WORLD !=

UART_GetOwnerID(uart_rtr_ind->port) )

{

// 如果底层能做成钩子链,这里就可以调用钩子链的下一个钩子了

return;

}

gwLenUartBuffer = read_from_uart(gabyUartBuffer,

sizeof(gabyUartBuffer), HELLO_WORLD_UART_PORT, MOD_HELLO_WORLD);

// 呼叫数据处理部分

uart_echo_process();

#endif

}

static void start_uart_echo(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

S8 strHello[] = "Hello World Uart Echo Example Started!\r\n";

if(gbUartEchoStarted)

{

return;

}

init_uart();

write_to_uart((kal_uint8*)strHello,

(kal_uint16)strlen(strHello), HELLO_WORLD_UART_PORT, MOD_HELLO_WORLD);

gbUartEchoStarted = KAL_TRUE;

SetKeyHandler(stop_uart_echo, KEY_LSK, KEY_EVENT_UP); #endif

}

static void uart_echo_process(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

U8 i;

// 稍稍处理一下,这样就能看出是否确实是我们的程序在处理数据 for(i = 0; i < gwLenUartBuffer; i++)

{

if(gabyUartBuffer[i] >= 'a' && gabyUartBuffer[i] <= 'z')

{

gabyUartBuffer[i] -= 0x20;

}

}

// 回显

write_to_uart(gabyUartBuffer, gwLenUartBuffer,

HELLO_WORLD_UART_PORT, MOD_HELLO_WORLD);

#endif

}

static void stop_uart_echo(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

S8 strBye[] = "Hello World Uart Echo Example Stop!\r\n";

if(gbUartEchoStarted)

{

write_to_uart((kal_uint8*)strBye,

(kal_uint16)strlen(strBye), HELLO_WORLD_UART_PORT, MOD_HELLO_WORLD);

gbUartEchoStarted = KAL_FALSE;

SetKeyHandler(start_uart_echo, KEY_LSK, KEY_EVENT_UP); }

exit_uart();

#endif

}

gdi_handle hAnimation;

void stop_play_anim(void)

{

gdi_anim_stop(hAnimation);

}

/* 模块入口 */

void mmi_HelloWorld_entry(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

S32 x, y, w, h;

color colorText = {255, 255, 128, 100};

color colorFill = {207, 252, 109, 100};

color colorShadow = {166, 201, 81, 100};

stFontAttribute tFont = {0};

U8 dotted_line_bitvalues[] = {1, 0, 1, 0, 1, 0, 1};

UI_filled_area tFiller = {0};

static color g_colors[3] = {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}; static U8 perc[2] = {50, 50};

gradient_color gc = {g_colors, perc, 3};

tFont.size = LARGE_FONT;

tFont.italic = 1;

/* 强制退出当前屏幕,之后进入到我们的模块了 */

/* 上电缺省是idle屏幕,现进入MAIN_MENU_SCREENID屏 */

/* 注意看第二个参数,这个是当我们模块被强制退出时执行的一些操作 */

EntryNewScreen(SCR_HELLOWORLD, mmi_HelloWorld_exit, NULL, NULL);

gui_lock_double_buffer();

/* 关掉屏幕顶部的状态条,我们要用整个屏幕 */

entry_full_screen();

/* 擦除当前背景 */

clear_screen();

tFiller.flags = UI_FILLED_AREA_TYPE_GRADIENT_COLOR | UI_FILLED_AREA_VERTICAL_FILL | UI_FILLED_AREA_DOUBLE_BORDER; tFiller.border_color = UI_COLOR_GREEN;

tFiller.gc = &gc;

gui_draw_filled_area(0, 0, UI_device_width - 1, UI_device_height - 1, &tFiller);

/* 设置字体颜色 */

gui_set_text_color(colorText/*UI_COLOR_RED*/);

gui_set_font(&tFont);

gui_set_text_border_color(UI_COLOR_GREEN);

gui_measure_string((UI_string_type)GetString(STR_HELLOWORLD_HELLO), &w, &h);

x = (UI_device_width - w) >> 1;

y = UI_device_height - ((UI_device_height - h) >> 2);

gui_draw_rectangle(x - 7, y - 7, x + w + 7, y + h + 7, UI_COLOR_RED); gui_fill_rectangle(x - 6, y - 6, x + w + 6, y + h + 6, colorFill); gui_line(x - 4, y + h + 4, x + w + 4, y + h + 4, colorShadow); gui_line(x - 5, y + h + 5, x + w + 5, y + h + 5, colorShadow); gui_line(x - 6, y + h + 6, x + w + 6, y + h + 6, colorShadow); gui_line(x + w + 4, y - 4, x + w + 4, y + h + 4, colorShadow); gui_line(x + w + 5, y - 5, x + w + 5, y + h + 5, colorShadow); gui_line(x + w + 6, y - 6, x + w + 6, y + h + 6, colorShadow); /* 移动文本输出光标 */

gui_move_text_cursor(x, y);

/* 输出文本到显示缓冲, 注意是Unicode编码 */

//

gui_print_text((UI_string_type)GetString(STR_HELLOWORLD_HELLO));

gui_print_bordered_text((UI_string_type)GetString(STR_HELLOWORLD_HELLO));

gdi_draw_line_style(x, y + h + 2, x + w + 2, y + h + 2, gdi_act_color_from_rgb(100, 255, 0, 0),

sizeof(dotted_line_bitvalues),

dotted_line_bitvalues);

// 显示图片

gdi_image_get_dimension_id(MAIN_MENU_MATRIX_ORGANIZER_ICON, &w, &h);

x = (UI_device_width - w) >> 1;

y = (UI_device_height - h) >> 1;

gdi_image_draw_id(x, 10, MAIN_MENU_MATRIX_ORGANIZER_ICON);

// 显示动画

gdi_image_get_dimension_id(MAIN_MENU_MATRIX_ORGANIZER_ANIMATION, &w, &h);

x = (UI_device_width - w) >> 1;

y = (UI_device_height - h) >> 1;

gdi_anim_draw_id(x, 10 + h,

MAIN_MENU_MATRIX_ORGANIZER_ANIMATION, &hAnimation);

gui_unlock_double_buffer();

/* 刷新屏幕显示,MMI用的是双缓冲绘图方式,而且需要显式刷新 */ gui_BLT_double_buffer(0, 0, UI_device_width - 1,

UI_device_height - 1);

/* 注册一个按键处理,右软键弹起时返回到之前被我们强制退出的模块 */

SetKeyHandler(GoBackHistory, KEY_RSK, KEY_EVENT_UP); // SetKeyHandler(stop_play_anim, KEY_LSK, KEY_EVENT_UP); SetKeyHandler(start_uart_echo, KEY_LSK, KEY_EVENT_UP); #endif

}

/* 模块出口

* 当我们的模块被其他模块强制退出时会执行这个函数,

* 这个函数的常见写法,包括:

* 1、模块已申请资源的释放(如果需要的话),这一步可选

* 2、手动把自己压栈到窗口(实际是整个屏)堆栈里面,

* 便于强制我们退出的模块执行完后重新把我们叫出来

* 不像Window的窗口管理是自动压栈的,Pluto MMI需要手动压栈 * 3、其他一些清理动作

*/

void mmi_HelloWorld_exit(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

history currHistory;

S16 nHistory = 0;

currHistory.scrnID = MAIN_MENU_SCREENID;

currHistory.entryFuncPtr = mmi_HelloWorld_entry;

pfnUnicodeStrcpy( (S8*)currHistory.inputBuffer,

(S8*)&nHistory);

AddHistory(currHistory);

stop_uart_echo();

#endif

}

void mmi_HelloWorld_hilite(void)

{

#ifdef __MMI_HELLOWORLD_ENABLED__

SetLeftSoftkeyFunction(mmi_HelloWorld_entry, KEY_EVENT_UP); #endif

}

void mmi_HelloWorld_init(void)

{

#ifdef

#endif

}

__MMI_HELLOWORLD_ENABLED__ SetHiliteHandler(MENU_ID_HELLOWORLD, mmi_HelloWorld_hilite);

相关推荐