1、短信的执行
在短信这边,与下层的消息交互都是通过action队列去做操作的,首先都会通过mmi_frm_sms_write_action(PsFuncPtrU16 callback, module_type mod_src, void *data, PsFuncPtr function)把要做的操作写进mmi_frm_sms_action队列里去(写入action队列的包括mmi_frm_sms_write_action传入的四个参数,callback、mod_src、data、function。function是当执行了read_action操作时执行function函数,在function函数中执行发送eventID,并注册响应消息的响应函数。在read_action后,开始执行用户的操作,即执行该evenID的响应函数,在该响应函数中执行mmi_frm_sms_callback_action()函数,并在该函数中执行mmi_frm_sms_action_curr = MMI_FRM_SMS_INVALID_NUM;把当前指针置为0xff,表示用户的一次操作完成。
)
这个action队列共有三个指针,head,taiil,curr,写是通过tail去写,在mmi_frm_sms_write_action()里
if (mmi_frm_sms_action_curr == MMI_FRM_SMS_INVALID_NUM)
{
mmi_frm_sms_read_action();
}
操作写完后会去做读的操作,这个时侯会把
mmi_frm_sms_read_action()
{
。。。。。。
mmi_frm_sms_action_curr = mmi_frm_sms_action_head;
}
头指针传给当前的指针,也就是说开始执行用户设定好的操作,只有当用户戶的一次操作完成后,通过调用
mmi_frm_sms_callback_action()
{
。。。。
mmi_frm_sms_action_curr = MMI_FRM_SMS_INVALID_NUM;
}
会再把当前指针置为0xff,表示用户的一次操作完成。
而mmi_frm_sms_check_action_pending()就是判断当前的mmi_frm_sms_action_curr当前指针是不是不为0xff,即当前还有与下层的交互操作沒有完成。之所以要有这个pending检查就是为了保证操作是一条条按顺序来执行的。
(我们的手机之所以会出现这个短信功能无法使用的问题,是因为我们在一些自己开发的功能中,调用了我们的mmi_frm_sms_write_action(),但是在执行完成之后,并沒有相应地调用mmi_frm_sms_callback_action()将指针还原,以至于无法执行下一次操作。MTK给出的问题可能出现的原因)
但是情况并不是MTK所提那样的。但是短信的处理流程MTK提的还是很好。我们的手机会出现短信功能无法使用确实是跟沒有相应地调用mmi_frm_sms_callback_action()将指针还原,以至于无法执行下一次操作,这个原因有关,但是出现这个情况的并不是我们调用了mmi_frm_sms_write_action()函数。
2、短信满的处理
2.1、我们原来所做的短信满处理
关于短信满,我们首先要做的是要随时动态的获取短信的条数(在程序中,我们添加一个函数dispose_sms_equal_or_greater_limit_count_req通过MMI层向L4C发送MSG_ID_MMI_SMS_GET_MSG_NUM_REQ这样一条消息,并注册L4C到MMI的消息MSG_ID_MMI_SMS_GET_MSG_NUM_RSP的响应函数dispose_sms_equal_or_greater_limit_count_rsp,在消息响应的函数将获得当前SIM卡和手机中存储的短信总条数)
我们在获得一条新短信的处理函数mmi_frm_sms_indicate_sms()、在开机准备短信模块的处理函数mmi_msg_handle_ready_ind()、在短信满的处理函数mmi_msg_handle_mem_full_ind()、在发送短信并保存的处理函数mmi_msg_save_msg_after_send_rsp()、在保存短信的处理函数mmi_msg_save_msg_rsp()中调用获取短信条数的函数dispose_sms_equal_or_greater_limit_count_req,并在
dispose_sms_equal_or_greater_limit_count_rsp函数中判断当前短信是否已经达到最大条数-2,如果是,则弹出提示框,提示用户需要删除短信。如果已经达到最大条数-1,我们将删除用户最早到达的一条短信,如果已经达到最大的存储容量,则自动删除用户最早到达的两条短信。
2.2、问题所在
3、编译过程遇到的一个问题
Error: L6218E: Undefined symbol Image$$ZI$$Limit (referred from sys_stackheap.o).
Not enough information to produce a SYMDEFs file.
Finished: 1 information, 37 warning and 1 error messages.
这个error的log很可能的原因是print,fprintf,malloc,strdup等内部使用了malloc函数的函数引起。
而我出现这个问题的原因是我在程序中调用了printf这个C标准库函数。MTK里面似乎是不支持这个函数。
4、如何修改快速查找窗口中information bar的信息。
原来的information bar主要是显示input box中能输入的字符个数和当前已经输入字符的个数。现在我们把它修改成显示总的电话号码的个数。
主要是修改文件:wgui_categories_inputs.c
函数:wgui_redraw_singleline_input_box_remaining_characters_display() 这个函数用来设置单行输入框的一些information。在函数中用gui_sprintf(str, "%d/%d", n, max_n);这个语句把当前输入字符个数(n)和能输入字符总数(max_n)用一个字符串来显示。最后gui_print_text(str);把该字符串显示在information bar中。那么我们在打印之前做个判断:
//falian add 20090313
if(GetActiveScreenId() == SCR_ID_PHB_QUICK_SEARCH_LIST) //获取当前的窗口ID,如果是快速查找的窗口ID
{
max_n = (S32)PhoneBookEntryCount;
gui_sprintf(str, "%d", max_n); //只显示当前总的电话号码的个数
}//end
5、mmi_bootup_is_nw_registration_ok(); 该函数可以用来判断SIM卡注册网络成功与否
Mmi_bootup_is_sim_valid(); 判断SIM卡是否有效
6、电话簿的快速查找用函数ShowCategory200Screen()显示
快速查找的输入框由函数wgui_setup_singleline_inputbox()设置显示风格,输入法等等也由该函数确定。
同时修改wgui_set_qsearch_default_input_type()函数来设置快速查找输入框的默认输入法
7、如何修改编辑短信时,当前剩余输入字符数随着输入法来改变
主要修改文件:wgui_ems.c和gui_ems.c
函数:void wgui_EMS_redraw_remaining_character_display(void)
和 S32 EMS_get_last_segment_remain_char()
wgui_EMS_redraw_remaining_character_display这个函数主要是用来设置短信编辑框中输入字符数和segment数。
该函数中
n = EMS_get_last_segment_remaining_char(&MMI_EMS_inputbox); //获取当前segment(应该是默认是第一个segment时)还能输入的字符数
max_n = EMS_get_required_segment(&MMI_EMS_inputbox); //当前编辑的是第几个segment信息
EMS_get_last_segment_remain_char这个函数主要是获取默认时,即未输入字符时短信编辑框能输入的字符数。
我们所要做的修改:
//falian modify 20090120 让短信提示个数随输入法的变化,而变化
if( MMI_current_input_mode == INPUT_MODE_SM_PINYIN ||
MMI_current_input_mode == INPUT_MODE_MMI_MULTITAP_PINYIN ||
MMI_current_input_mode == INPUT_MODE_SM_STROKE ||
MMI_current_input_mode == INPUT_MODE_SM_MULTITAP_PINYIN )
{
//当当前输入法为中文和笔画时,显示输入个数为70个
RemainingChar = 70;
kal_prompt_trace(MOD_MMI,"编辑短信");
}
else
{
RemainingChar = (S32)input_data->data->Reminder.segRemainingOctet;
}
8、socket的阻塞模式和非阻塞模式的区别是什么
就和SendMessage()和PostMessage()的区别一样
阻塞模式下, 程序在调用接收函数时(如recv), 如果没有数据到达, 此函数会一直等待, 即当前线程会被阻塞, 直到有数据时才返回!
换句话说,没有数据到达时,程序回在这行代码上等待,不继续往下执行。有数据到达后,函数返回,程序才往下执行
在非阻塞模式下, 程序在调用接收函数时, 接收函数会立即返回, 调用方还可以进行其它操作, 而当有数据到达进, 操作系统会通过某些方法(如事件)来通知你!
换句话说,不论是否有数据到达,程序一直往下执行。而数据到达后,操作系统会通知程序,程序根据操作系统通知的信息来做相应处理。
9、MTK 图层,详细讲解加案例
在某些频繁更新的界面中,如果某些显示元素一直没有变化,我们就可以将这些元素提取出来画到一个模拟的屏幕中,而将一些需要更新的元素画到另外的模拟屏幕, 而后将两个模拟屏幕合并到真正的屏幕上,这样我们就节省了不变元素的重画时间,从而减轻了系统负担及加速画面更新。我们把这样的模拟屏幕就叫层,也可以说层就是屏幕的缓冲空间。
例如,如果我们用动画做为背景,将其他的一些元素也画到这一层中,就会出现当动画跳到第二帧后,动画上面的文本及图象都会被盖住。而有了层以后,我们就可以将不变的文本及图象放到新建的一个层中,将动画放到背景层中,每当有动画换帧时,只需将新帧画到背景层中,然后合并两个屏幕(动画刷新时会自动合并),这样上层的文本等就不会被盖住了。
另外,因为层的格式简单且统一,并且一般的图形系统都会用硬件加速合并,所以在层合并时加上些特效会很方便,如通透、半透明、剪切等。
下面将以mmi_phoart_entry_main_screen()为例说明关于层的一些内容。
1.首先,因为用到两个层,所以我们要开启多层
gdi_layer_multi_layer_enable();
等到退出该屏幕的时候需要gdi_layer_multi_layer_disable();
2.创建层:创建层需要先建一个层句柄,我们可以通过该句炳来控制层,函数gdi_layer_create用来创建层
gdi_layer_create(OFFSET_X,OFFSET_Y,WIDTH,HEIGHT,HANDLE_PTR);
OFFSET_X,OFFSET_Y 是层的位置坐标,WIDTH,HEIGHT是层的大小;HANDLE_PTR是层句炳,用于返回所创建的层。不过,因为创建层时系统要为其分配动态内存空 间,而系统保留的内存一般只够创建一个UI_device_width*UI_device_height大小的层,所以如果已有两个层,而需要再创建新 层时,就需要用到函数 gdi_layer_create_using_outside_memory(X,Y,WIDTH,HEIGHT,HANDLE_PTR,OUTMEM_PTR,OUTMEM_SIZE)
前5个参数和gdi_layer_create的参数相同,OUTMEM_PTR是存放层的BUFFER,OUTMEM_SIZE是层的大小。
3. 激活层:在我们的图形系统中,任何时刻有且只能有一个层处于激活状态,所有的绘画都会默认画到这个激活层中,所以想要在层上绘画必须先将其激活。激活函数 是gdi_layer_set_active(gdi_handle handle);不过,由于在多层的处理中需要在各个层之间切换激活,所以我们经常用到的是 gdi_layer_push_and_set_active(gdi_handle handle),此函数会把当前的激活层入栈而激活参数层,等到下次需要激活栈中的层时,只需要用函数 gdi_layer_pop_and_restore_active()激活就可以了。
4.基础层:系统开机的时候会为每个硬件屏幕创建一个基础层,基础层有以下几个特点:
(1)基础层由系统创建,无法删除。
(2)与硬件屏幕完全重合。
(3)系统默认的激活层,EntryNewScreen时系统会紫铜将基础层激活。
(4)显示更加快速,基础层存储于芯片内的flash中,所以在其上面绘画极快,一般我们会将刷新频繁的内容放在基础层上。
基 于以上几点,通常在不使用多层的情况下,我们完全可以将基础层当成硬件屏幕来看待,也就是说普通程序完全可以忽略层的概念。另外,因为系统一般只在 EntryNewScreen时才会自动将基础层激活,为避免特殊情况下使用层混乱,通常在新层上绘画完毕后我们会主动将基础层还原为激活状态。
其 实,对于我们上面说到的层之间的切换激活而言,大多说情况下是基础层和新层之间的切换。为此需要用到 gdi_layer_get_active(gdi_handle *handle_ptr)得到当前激活层句柄(多数情况下是基础层句柄),这样我们就可以切换激活层了。
5.合并:有了多个层,当然要合并到一起 了。合并层的函数是gdi_layer_blt_previous(S32 x1, S32 y1, S32 x2, S32 y2),gui_BLT_double_buffer也具有同样的效果。另外,在合并前,我们还需要用函数 gdi_layer_set_blt_layer(H1,H2,H3,H4) 来指明需要合并的层。
6。释放:由于空间的问题,我们创建的新层在用完后一定要释放,释放函数是:
gdi_layer_free(gdi_handle handle)。注意:层一般是在退出函数中释放。
说到这儿,我们就可以建立一个多层的屏幕了。下面我们在看看层的一些特效:
1. 剪切:所谓剪切,就是在层中设一个限制区域,只有在这个区域中的绘画才是有效的,否则就会被自动忽略。剪切有两个显著的特点,一是每个层一定而且只能有一 个剪切区域。二是剪切区域一经设置将永远生效。所以剪切区域用完后最好用gdi_layer_reset_clip()还原。剪切用函数 gdi_layer_set_clip()来实现。
2.通透:所谓通透,就是如果我们将某种颜色设为通透色,在层合并的时候,系统会自动将层中与 通透色相同的颜色忽略掉,这样我们在这一点上看到的是其下层的颜色。设置通透的函数是gdi_layer_set_source_key。另外在设置通透 前我们通常用gdi_layer_clear_background将该层刷上某种颜色。
3.透明:gdi_layer_set_opacity(BOOL opacity_enable, U8 opacity_value)
opacity_enable指通明是否开启,opacity_value指透明度,范围是0至255,值越小越透明。
4. 锁屏:由于某些元素要频繁的刷新,而如果我们每次都合并就会很浪费时间,因此我们可以设置两个计数器,一个用来加,一个用来减,当计数器为0时,我们再合 并。这两个计数器就是 gdi_layer_lock_frame_buffer()和 gdi_layer_unlock_frame_buffer();
请参考以下进入一个新屏的函数:
static void mmi_entry_new_screen(void)
{
S8 buf_filename[FMGR_PATH_BUFFER_SIZE];
S32 image_width;
S32 image_height;
PU8 buf_ptr;
U8 *gui_buffer;
GDI_RESULT result;
S32 offset_x;
S32 offset_y;
U16 img_type;
UI_string_type title_string;
S32 str_width;
S32 str_height;
EntryNewScreen (SCR_ID_PHOART_MAIN,mmi_phoart_exit_main_screen,mmi_phoart_entry_main_screen, NULL);
gdi_layer_reset_clip();//设置剪切区域
gdi_layer_reset_text_clip();//设置剪切区域
//gui_set_font(&MMI_medium_font);
gui_buffer = GetCurrGuiBuffer(SCR_ID_PHOART_MAIN);
entry_full_screen();
gdi_layer_multi_layer_enable();//开启多层
gdi_layer_get_active(&g_phoart_cntx.base_layer_handle);//得到当前活动层
gdi_layer_get_source_key(&g_phoart_cntx.was_source_key_enable, &g_phoart_cntx.old_source_key);//得到当前活动层的通透属性
gdi_layer_set_source_key(FALSE, g_phoart_cntx.old_source_key);//设置通透
gdi_layer_create(0, 0, UI_device_width, UI_device_height, &g_phoart_cntx.osd_layer_handle);//创建新层
gdi_layer_push_and_set_active(g_phoart_cntx.osd_layer_handle);//激活新层
gdi_layer_clear_background(GDI_COLOR_TRANSPARENT);//刷色
gdi_layer_set_source_key(TRUE, GDI_COLOR_TRANSPARENT);//设置通透
//base layer
gdi_layer_pop_and_restore_active();//激活栈中的层
//gdi_layer_reset_clip();
//gdi_layer_reset_text_clip();
gdi_layer_clear_background(GDI_COLOR_RED);
gdi_layer_set_source_key(TRUE, GDI_COLOR_RED);
gdi_image_stop_animation_all();
gdi_image_draw_animation_id(50, 100, IMG_ID_PHOART_ICON_6, NULL);
//new layer
gdi_layer_push_and_set_active(g_phoart_cntx.osd_layer_handle);
// gdi_layer_reset_clip();
//gdi_layer_reset_text_clip();
gdi_layer_set_clip(0,0,50,50);
gdi_layer_clear_background(GDI_COLOR_TRANSPARENT);
gdi_layer_set_source_key(TRUE, GDI_COLOR_TRANSPARENT);
gui_set_font(&MMI_medium_font);
gui_set_text_color(g_phoart_cntx.text_color);
gui_set_text_border_color(g_phoart_cntx.text_border_color);
title_string = (UI_string_type) get_string(STR_ID_PHOART_APP);
gui_measure_string(title_string, &str_width, &str_height);
gdi_layer_set_clip((UI_device_width - str_width) >> 1,(MMI_title_height - str_height) >> 1,200,100);//设置剪切区域
gui_move_text_cursor((UI_device_width - str_width) >> 1, (MMI_title_height - str_height) >> 1);
gui_print_bordered_text(title_string);
mmi_phoart_draw_softkey((PS8) get_string(STR_GLOBAL_OPTIONS), (PS8) get_string(STR_GLOBAL_BACK), FALSE);
gdi_layer_pop_and_restore_active();
gdi_layer_set_blt_layer(g_phoart_cntx.base_layer_handle, g_phoart_cntx.osd_layer_handle, 0, 0);//指明需要合并的层
gdi_layer_blt_previous(0, 0, UI_device_width - 1, UI_device_height - 1);//合并层
}
10、系统的关机处理函数ShutdownSystemOperation(),完成关机的操作
11、关于手机中日历的界面
1、日历界面的风格由函数gui_calendar_set_current_theme根据当前主题来设定。主要包括一些颜色等的设定。
2、日历界面的组织由函数gui_calendar_create来完成。主要包括比如信息栏、日历的垂直显示周次的垂直信息栏,已经显示日期的日期框等。
3、在日历上的按键响应通过函数gui_calendar_set_keyhandler来设定。
4、当键移动时,总有一项是高亮显示的,那么这个高亮的日期的显示由函数
gui_calendar_highlight_cell()函数处理。Mtk默认的显示是画一个矩形框,用函数
gdi_draw_rect,该函数中的参数
gdi_act_color_from_rgb(c->cell_highlight.alpha, c->cell_highlight.r, c->cell_highlight.g, c->cell_highlight.b));画矩形框的颜色。其中c->cell_highlight.r等用到的颜色是在主题风格中设定好的,颜色的设定具体看theme的结构。
如果想让高亮的显示实心的矩形框,则需要用到函数
gdi_draw_solid_rect,该函数的颜色参数一般选用
gdi_act_color_from_rgb(c->cell_bg[GUI_CALENDAR_COLOR_CURRENT].alpha, c->cell_bg[GUI_CALENDAR_COLOR_CURRENT].r, c->cell_bg[GUI_CALENDAR_COLOR_CURRENT].g, c->cell_bg[GUI_CALENDAR_COLOR_CURRENT].b));
该函数可以绘制成底色,具体的颜色设定也是由主题风格确定。
5、mtk中设定的日期如果写了备忘录,那么该日期会用水平的横条或者是垂直的竖条带颜色的框来填充。
如果想要修改,只要修改函数static void gui_calendar_redraw_cell()
函数中有
if (c->cell_array.bg_fill_type == GUI_CALENDAR_CELL_BG_FILL_HORIZONTAL)
{}
else if(c->cell_array.bg_fill_type == GUI_CALENDAR_CELL_BG_FILL_VERTICAL)
{}
的判断,修改里面的坐标值就行了。
12、mtk中的cmnet和cmwap
1、net就是tcp,wap是必须符合移动的http协议,,
2、包括gprs设置、socket、http、网络重联、wap net等等,,
3、sprintf(request.head,
"Host: %s:%d/r/n"
"X-Online-Host: %s:%d/r/n"
"User-Agent: Nokia6681/2.0 (3.10.6) SymbianOS/8.0 Series60/2.6 Profile/MIDP-2.0 Configuration/CLDC-1.1/r/n"
"Accept: */*/r/n"
"Accept-Language: zh-cn/r/n"
"Accept-Encoding: gzip, deflate/r/n"
"Content-Type: application/octet-stream/r/n"
"Content-Length: %d/r/n",
session->host, session->port,
session->host, session->port,
body_len); 这是wap http头,net可使用自定义简单http头,这样做协议层可统一起来处理,,然后还有一个注意点就是wap在连接是,移动网关可能会推送一个确认http包,这个要特殊处理掉,,判断出后重新发送原请求包就可以了,,判断的方法有很多,保险的方法是可以在http的body头几个字节存放识别码,,识别码不对就可以断开重联了,,在http的body头几个字节存放识别码,这个应该是在服务器端实现的,,另外net和wap统一起来处理时要注意socket层收到的数据包可能存在多个http响应报文,需一一处理,,http服务器采用1.1协议,1.0协议http body部分难以识别,,http协议中实际使用中应该统一使用post协议就可以了,其他的都用不到,,
但是如果你访问别的服务器就不行了啊 ,,wap是http代理协议,和其他代理协议一样,数据包要特殊处理 ,net是直连 ,这个网络的区分本质上不同协议导致的 ,,
4、想知道移动推送的资费页的内容,你大可以get出来,然后显示一下,然后根据这个页面的特点写一个自己的判断函数。MTK现在手机最新版本支持 HTTP1.1
5、在PC机上访问动态页面返回都是chunked编码,但是在手机上却可以获取Content-Length,怎么回事?
司令(52400840) 15:32:24
你手机上网是通过了移动的服务器了
一笑而过<maqian.cn@gmail.com> 15:32:45
你是说是移动网关加上的?
司令(52400840) 15:35:24
你是通过移动网关入网的,那它拉了数据回来后做了什么处理再给你你就得接受它。反正你和万维网是不能直连的
一笑而过<maqian.cn@gmail.com> 15:36:48
如果是这样,那岂不是移动网关先暂存该页面的所有数据,然后再返回给客户端,要不然它不可能指定Content-Length,但是一个服务器做这样的处理,基本上是不可能的
司令(52400840) 15:37:35
服务器是任何处理都能做
司令(52400840) 15:39:06
移动的服务器在不同的地区都有独立的。相当于中继站一样,分布管理的。所以在使用手机上网人多的城市,手机网速就很明显慢很多
一笑而过<maqian.cn@gmail.com> 15:40:16
我相信你说的是对的,但是这不能代表服务器会对一个页面的所有数据做缓存
司令(52400840) 15:40:28
你做手机没学过GSM通信原理吗?不管是通话还是数据,都是蜂窝式的管理。哪有可能全国就公用一个服务器
司令(52400840) 15:40:59
具体如何做我也不清楚。但是这是一个很可能的方式
一笑而过<maqian.cn@gmail.com> 15:42:09
惭愧,我还真没学过
司令(52400840) 15:42:26
现在做LINUX服务器很吃香。也是因为客观上的确需求硬件和软件搭配一流。而且性能优越
司令(52400840) 15:43:48
一般来说我们比较容易看到的是服务器的硬件在不断升级了。但是软件还是有专业公司在做优化的,专门针对服务器。
一笑而过<maqian.cn@gmail.com> 15:53:12
不好意思,我是说我在PC机和手机上用同样的HTTP头请求同一个动态页面,但是返回的页面是两种不同的编码方式,PC机上收到的内容是用chunked方式编码的,(也就是说是分多次发过来的),但是手机收到的内容是一次性发过来的,(也就是说返回的http头部中含有Content-Length信息)
司令(52400840) 15:58:40
你pc是通过路由器和MODEM直连到中国电信的大路由器,然后通过ARP直接与目标服务器或PC机通信获取的网页数据,当然是分多次分包拉回来的。
但是你手机是通过移动的服务器去拉数据,然后移动的服务器再给你发的。
司令(52400840) 15:59:18
很明显有了移动服务器这一个中间者的加入了
一笑而过<maqian.cn@gmail.com> 16:07:36
我知道有这个差别,但是这个说明不了问题。
如果服务器暂存页面的话,会存在空间和效率的问题,你说移动的服务器很多,但我想总不会有用户多,还有这样做会造成访问页面的延时,并且移动服务器需要对每一个请求的页面数据进行解码
司令(52400840) 16:08:49
你知道LINUX操作系统是多进程多线程的吗
一笑而过<maqian.cn@gmail.com> 16:09:23
windows也是啊
超级男声(9932916) 16:09:33
dos 不是 嘿嘿
JacksonPan<ac861219@gmail.com> 16:09:51
我咋觉得windows不能把所有进程和线程独立开来
司令(52400840) 16:09:52
既然服务器能够做网站给你拉数据,那就说明服务器的性能和效率是不容质疑的
JacksonPan<ac861219@gmail.com> 16:09:56
而linux真的做到了
司令(52400840) 16:10:18
是的。LINUX是真正做到了。
潇洒中的忧郁(199439896) 16:11:20
移动的服务器是Seloris的
JacksonPan<ac861219@gmail.com> 16:12:04
windows貌似都是连贯的,一旦有些应用挂了,连带exporlor也挂了
司令(52400840) 16:14:54
所以一些用IIS做的网站服务器连20个同时链接请求都处理不过来
JacksonPan<ac861219@gmail.com> 16:15:57
恩
13、mtk修改手机的串口
手机中总共有三个串口,如果用户想要修改,可以在文件Nvram_common_config.c中找到结构体static port_setting_struct const NVRAM_EF_PORT_SETTING_DEFAULT[]
修改其中的值,可以改变串口的功能。
结构体port_setting_struct的结构如下:
typedef struct
{
kal_uint16 tst_port_ps;
kal_uint16 ps_port;
UART_baudrate tst_baudrate_ps;
UART_baudrate ps_baudrate;
kal_bool High_Speed_SIM_Enabled;
kal_uint8 swdbg;
kal_uint8 uart_power_setting; /* For DCM, Start [Set UART POWER], CTI */
kal_uint8 cti_uart_port;
UART_baudrate cti_baudrate;
kal_uint8 tst_port_l1;
UART_baudrate tst_baudrate_l1;
// Support tst output to memory card
kal_uint8 tst_output_mode;
} port_setting_struct;
14、添加一个文件夹或者是文件遇到的问题
Mtk中添加了一个文件一般是在plutommi中添加文件夹。在custom里面不能添加文件夹,只能在已经有的文件夹下添加新的文件。
在plutommi里面添加了文件夹,要记住在make中找到相应的模块,把相对路径加进去。这个是ARM编译器在编译的时候需要的一个路径。
在新增加的文件当中,可能需要包含一些mtk已经有的头文件。注意头文件包含的顺序有一定的要求,注意不要重复包含。(这个我也不知道怎么解决,只能自己慢慢的尝试)
15、添加一个GPS模块
在手机中添加一个GPS应用模块的大致步骤:
GPS是一个外设,所以需要通过一个接口,把gps的数据写入和读出。23上设置的都是gpio49,作为gps的接收,gpio51为gps的发送。Gpio43给gps一个启动的电平。Gps与手机采用串行的数据通信。手机中为gps分配了串口2—UART2。
那么这段代码为:
// 改变串口2的享有模块
UART_SetOwner(uart_port2, MOD_CUSTOM2);
UART_SetBaudRate(uart_port2, UART_BAUD_9600 ,MOD_CUSTOM2);
UART_ClrRxBuffer(uart_port2,MOD_CUSTOM2);
UART_ClrTxBuffer(uart_port2,MOD_CUSTOM2);
这样,gps就能通过串口2,向CUSTOM2发送读写的消息。
当CUSTOM2收到消息MSG_ID_UART_READY_TO_READ_IND后,在CUSTOM2里面调用kal_uint16 UART_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid);从串口读取数据。
17、NVRAM的相关知识和如何添加一个新的NVRAM LID
1、LID的定义有两个地方,分别是MT区域和CT区域。
NVRAM LID的定义分别定位在如下文件中:
Nvram_data_items.h:这个是为MTK系统所用
Nvram_data_items.c:这个也是为MTK系统所用
Nvram_user_defs.h:这个是为用户定义LID所使用
Nvram_user_config.c:这个是为用户定义LID使用
2、META工具所描述的信息主要是存储在如下文件:
Nvram_editor_data_item.h:这个是为系统使用
Custom_nvram_editor_data_item.h:这是为用户定义的lid所使用
3、NVRAM的lid的描述
NVRAM的lid由变量ltable_entry_struct这个结构体来描述,主要的成员变量有:
18、修改手机的主题菜单风格
在函数InitPhoneSetupCntx()中有一个从NV获取默认主题风格的代码,如果获取的值为空,则程序上设置默认的主题风格,代码如下:
#ifdef __MMI_MAINMENU_STYLE_CHANGE_EN__
ReadValue(NVRAM_SET_MAINMENU_STYLE, &(g_phnset_cntx_p->MenuStyle), DS_BYTE, &Err);
if (g_phnset_cntx_p->MenuStyle == 0xFF || g_phnset_cntx_p->MenuStyle >= PHNSET_MAINMENU_STYLE_MAX)
{
#if 0 // liaozhi 081006 修改主菜单显示风格为循环菜单
g_phnset_cntx_p->MenuStyle = 0;
#else
//#ifdef __MMI_MAINMENU_ROTATE_SUPPORT__
#ifdef __MMI_MAINMENU_PAGE_SUPPORT__
//g_phnset_cntx_p->MenuStyle = PHNSET_MAINMENU_STYLE_ROTATE;
g_phnset_cntx_p->MenuStyle = PHNSET_MAINMENU_STYLE_PAGE; //把默认的风格设置为单页式的
#else
g_phnset_cntx_p->MenuStyle = 0;
#endif
#endif
}
#endif /* __MMI_MAINMENU_STYLE_CHANGE_EN__ */