Melis4.0[D1s]:2.启动流程(GUI桌面加载部分)跟踪笔记 您所在的位置:网站首页 荔枝派nano能用来做什么 Melis4.0[D1s]:2.启动流程(GUI桌面加载部分)跟踪笔记

Melis4.0[D1s]:2.启动流程(GUI桌面加载部分)跟踪笔记

#Melis4.0[D1s]:2.启动流程(GUI桌面加载部分)跟踪笔记| 来源: 网络整理| 查看: 265

文章目录 0. 控制台输出信息等级设置0.1 设置log level = 4 无法正常启动 1.宏观启动流程1.1 控制台入口函数finsh_thread_entry()执行《startup.sh》1.2 《startup.sh》启动桌面GUI模块1.2.1 《startup.sh》加载 desktop.mod1.2.2 desktop.mod加载 init.axf1.2.3 init.axf 介绍1.2.3.1 INIT_MOpen()调用application_init_process()启动消息死循环1.2.3.2 application_init_process()调用gscene_bgd_init()设置背景图片1.2.3.3 application_init_process()调用_process_init() 2. GUI桌面app加载2.1 app_root.axf 介绍2.2 主函数 app_root_start()调用app_root_wincreate()创建根窗口2.2 主函数 _home_on_create()调用init_multi_screen_res()初始化图片、文字资源2.3 dsk_theme_open() 通过ID获取图片数据 3.绘制主界面3.1 draw_multi_screen_icon_coor_rect()函数调用表格 在阅读Melis4.0GUI加载流程,顺手做笔记,供自己查阅。

0. 控制台输出信息等级设置

为了方便跟踪代码执行流程,可以参考控制台的输出信息。控制台输出调试信息有6个等级,分别为0-5:

#define OPTION_LOG_LEVEL_CLOSE 0 #define OPTION_LOG_LEVEL_LOG 1 #define OPTION_LOG_LEVEL_ERROR 2 #define OPTION_LOG_LEVEL_WARNING 3 #define OPTION_LOG_LEVEL_INFO 4 #define OPTION_LOG_LEVEL_MESSAGE 5

在GUI源码中,有很多INFO级别的调试信息,可以打开观察学习: 在这里插入图片描述

0.1 设置log level = 4 无法正常启动

设置log level = 4,测试了一下,显示开机界面后就死机了,一直打印下面的信息,等了几分钟都没有反应:

[INF]: [riscv_cpu_handle_exception:0271]: ecall SYSCALL_FROM_S

只好设置为log level = 3 。可以正常使用,但是界面切换比 log level = 2会慢一点。

1.宏观启动流程

Melis启动顺序的介绍在《Melis4.0 RTOS_方案快速开发指南》,这里先上一张该文档的截图: 在这里插入图片描述

1.1 控制台入口函数finsh_thread_entry()执行《startup.sh》

这个函数在文件 《ekernel\subsys\finsh_cli\shell_entry.c》 中,在进入cli(command line interface)之前,会执行《startup.sh》文件。 在这里插入图片描述

1.2 《startup.sh》启动桌面GUI模块 1.2.1 《startup.sh》加载 desktop.mod

该文件的路径为 《projects\d1s-mq\data\UDISK\startup.sh》 ,内容如下:

echo "Execute startup script begin.............." #insmod d:\mod\display.mod insmod d:\mod\orange.mod insmod d:\apps\desktop.mod echo "...............Execute startup script end"

desktop.mod就是桌面GUI的入口app。它主要由《D1s-Melis\livedesk\beetles\mod_desktop\》目录下的文件编译链接产生。该目录下的Makefile文件:

ccflags-y += -DEPDK_DEBUG_LEVEL=EPDK_DEBUG_LEVEL_LOG_ALL \ -DUSED_BY_DESKTOP \ $(SOLUTION_INCLUDE) usrlibs-y += -L$(srctree)/${elibrary-libs}/ \ --start-group \ -lsyscall -lminic \ -llzma -lcharset \ -lmediainfo \ --end-group #-lmediainfo MOD_NAME := desktop SUF_NAME := mod PRJ_PATH := $(MELIS_BASE)/projects/${TARGET_BOARD}/data/UDISK/apps/ TEMP_PATH := $(MELIS_BASE)/emodules/bin $(MOD_NAME)-objs += desktop_api.o $(MOD_NAME)-objs += mod_desktop.o $(MOD_NAME)-objs += magic.o $(MOD_NAME)-objs += built-in.o $(MOD_NAME)-objs += engine/ $(MOD_NAME)-objs += framework/ $(MOD_NAME)-objs += functions/ $(MOD_NAME)-objs += msg_srv/ $(MOD_NAME)-objs += util/ include $(MELIS_BASE)/scripts/Makefile.mods 1.2.2 desktop.mod加载 init.axf

mod_desktop.c 中加载GUI的函数 DESKTOP_MOpen()代码,其中的 init.axf 就是完成GUI准备工作可执行文件 :

__mp *DESKTOP_MOpen(__u32 mid, __u32 mod) { __log("DESKTOP_MOpen."); int ret = -1, value = 0; desktp_data.mid = mid; ret = esCFG_GetKeyValue("card_product", "card_product_used", (int32_t *)&value, 1); if (ret == -1 || value == 0) { desktp_data.init_id = esMODS_MInstall(BEETLES_APP_ROOT"apps\\init.axf", 0); } else if (value) { desktp_data.init_id = esMODS_MInstall(BEETLES_APP_ROOT"apps\\init_sd_product.axf", 0); } desktp_data.init_mp = esMODS_MOpen(desktp_data.init_id, 0); return (__mp *)&desktp_data; } 1.2.3 init.axf 介绍

请注意,这里有2个C文件名很相似:init_mod.c 和 mod_init.c 。 init.axf由 《livedesk\beetles\init》 目录下的源码编译链接产生。看看该目录下的Makefile部分内容: 在这里插入图片描述 主要函数INIT_MOpen()在文件 《livedesk\beetles\init\mod_init.c》 中:

__mp *INIT_MOpen(__u32 mid, __u32 mod) { __inf("----------------------INIT_MOpen --------------------------\n"); msg_emit_init(); init_data.mid = mid; init_data.init_tid = esKRNL_TCreate(application_init_process, NULL, 0x10000, KRNL_priolevel3); esKRNL_TaskNameSet(init_data.init_tid, "initprocess"); if (init_data.init_tid == 0) { __err(" application_init_process main thread create error\n"); return NULL; } return (__mp *)&init_data; } 1.2.3.1 INIT_MOpen()调用application_init_process()启动消息死循环

application_init_process()在文件 《livedesk\beetles\init\init_mod.c》 中:

void application_init_process(void *arg) { ..... __log("%s %d before init_mainwin_create", __FUNCTION__, __LINE__); init_mainwin = init_mainwin_create(); ..... _process_init(); __log("%s %d before GUI_GetMessageEx", __FUNCTION__, __LINE__); /* message loop*/ while (GUI_GetMessageEx(&msg, init_mainwin)) // 消息循环 { #ifdef __MSG if (msg.id != GUI_MSG_TIMER) { __msg("msg.h_deswin=%x, msg.id=%d, msg.dwAddData1=%d,msg.dwAddData2=%d", msg.h_deswin, msg.id, msg.dwAddData1, msg.dwAddData2); } #endif ret = GUI_DispatchMessage(&msg); // 分发消息到回调 if (msg.p_arg) // 同步消息回应 { GUI_SetSyncMsgRetVal(&msg, ret); GUI_PostSyncSem(&msg); } } __log("%s %d want to shutdown_logo_show", __FUNCTION__, __LINE__);// add by hwd00001 ..... }

上面的代码一直停留在消息循环中,正常情况不会退出循环。我在消息循环后面加了打印log信息,一直没有看到log输出。

1.2.3.2 application_init_process()调用gscene_bgd_init()设置背景图片 逐级调用函数所在文件application_init_process()livedesk\beetles\init\init_mod.cgscene_bgd_init()livedesk\beetles\init\background\gscene_backgrd.cgscene_bgd_set_status_show()livedesk\beetles\init\background\gscene_backgrd.cgscene_bgd_update_filename()livedesk\beetles\init\background\gscene_backgrd.cgscene_bgd_get_default_file()livedesk\beetles\init\background\gscene_backgrd.cget_logo_mode()livedesk\beetles\init\background\fb_lib\backlayer_lib.c

这里重点分析一下get_logo_mode():

uint32_t get_logo_mode(void) { if (esCFG_GetKeyValue("backlayer", "backlayer_mode", &bk_mode, 1) != EPDK_OK) { bk_mode = 0; __err("get_logo_mode err!"); } return bk_mode; }

esCFG_GetKeyValue()函数是从 sys_config_nor.fex 中读取键值,这里是 backlayer_mode=0: 在这里插入图片描述 gscene_bgd_get_default_file()于是获取的图片名称为 res\bg_default0.jpg ,对应的SDK目录下的 《projects\d1s-mq\data\UDISK\res\bg_default0.jpg》 ,只要更换这个图片,使用相同的名称,就可以改变背景图片。 sys_config.fex 的读写可参考官方文档《Melis4.0_RTOS_配置(sys_config)_开发指南.pdf》 gscene_bgd_get_default_file()部分源码:

static int32_t gscene_bgd_get_default_file(char *filename) { int32_t index; char path[BG_MAX_CHAR_LEN] = {0}; index = gscene_bgd_get_default_bg_index(); if (get_logo_mode() == JPG_MODE) { eLIBs_sprintf(path, "%sbg_default%d.jpg", BG_DEFAULT_PATH, index); } else { eLIBs_sprintf(path, "%sbg_default%d.bgd", BG_DEFAULT_PATH, index); } ...... } 1.2.3.3 application_init_process()调用_process_init()

application_init_process()和_process_init()位于同一个C文件。

static void _process_init(void) { H_WIN scene_adjust; int32_t flag = 2; char load_para[1024] = {0}; _framework_init(); #if CONFIG_SUPPORT_TOUCHPANEL open("/dev/tpadc_rtp", O_WRONLY); #endif eLIBs_memcpy(load_para, &flag, 4); __msg("********_process_init***********"); activity_set_load_para("root", "", load_para, sizeof(load_para)); activity_load_app("application://app_root"); }

到此处,加载 app_root.axf,启动GUI桌面程序。

2. GUI桌面app加载 2.1 app_root.axf 介绍

app_root.axf由 《livedesk\beetles\sun20iw1_app\apps》 目录下的源码编译链接产生。看看该文件下的Makefile部分内容: 在这里插入图片描述

2.2 主函数 app_root_start()调用app_root_wincreate()创建根窗口

app_root_start()在文件 《livedesk\beetles\sun20iw1_app\apps\app_root\app_root.c》 中:

/********************************************************************************************************************** 插件接口实现 **********************************************************************************************************************/ static int32_t app_root_start(Activity *activity) { __inf("**************app_root plugin start!**************** \n"); __inf("****************************\n"); app_root_init_res(); root_activity = activity; happ_root_manwin = app_root_wincreate(activity); if (NULL == happ_root_manwin) { __inf(" app_root_wincreate fail! \n"); return EPDK_FAIL; } else { GUI_WinSetFocusChild(happ_root_manwin); __inf(" app_root_wincreate success! \n"); return EPDK_OK; } }

E:\C_code\D1s-Melis\livedesk\beetles\sun20iw1_app\apps\app_root\app_root_scene.c

逐级调用函数所在文件app_root_start()livedesk\beetles\sun20iw1_app\apps\app_root\app_root_scene.capp_root_wincreate()livedesk\beetles\sun20iw1_app\apps\app_root\app_root_scene.capp_root_win_proc()livedesk\beetles\sun20iw1_app\apps\app_root\app_root_scene.capp_home_create()livedesk\beetles\sun20iw1_app\apps\multi_screen_home\app_multi_screen_home.c_home_on_create()livedesk\beetles\sun20iw1_app\apps\multi_screen_home\desktop_scene\desktop_scene.cdesktop_scene_create()livedesk\beetles\sun20iw1_app\apps\multi_screen_home\desktop_scene\desktop_scene.c 2.2 主函数 _home_on_create()调用init_multi_screen_res()初始化图片、文字资源

跟踪到这里,虽然还不知道如何显示界面的图片,不过已经明白如何替换图片了。 init_multi_screen_res()初始化主界面的8个图片(每个图片分焦点和非焦点2种),8个字符串。

static const __s32 multi_screen_uf_icon[HOME_UNFOCUS_ICON_NUM] = { //固定应用 ID_HOME_NEW_EXPLORER_UF_BMP, ID_HOME_NEW_MOVIE_UF_BMP, ID_HOME_NEW_MUSIC_UF_BMP, ID_HOME_NEW_PICTURE_UF_BMP, ID_HOME_NEW_EBOOK_UF_BMP, ID_HOME_NEW_FM_UF_BMP, ID_HOME_NEW_RECORD_UF_BMP, ID_HOME_NEW_SETTING_UF_BMP, }; static const __s32 multi_screen_f_icon[HOME_FOCUS_ICON_NUM] = { //固定应用选中 ID_HOME_NEW_EXPLORER_FC_BMP, ID_HOME_NEW_MOVIE_FC_BMP, ID_HOME_NEW_MUSIC_FC_BMP, ID_HOME_NEW_PICTURE_FC_BMP, ID_HOME_NEW_EBOOK_FC_BMP, ID_HOME_NEW_FM_FC_BMP, ID_HOME_NEW_RECORD_FC_BMP, ID_HOME_NEW_SETTING_FC_BMP }; static const int32_t multi_screen_string[MULTI_SCREEN_STRING_MAX] = { STRING_HOME_EXPLORER, STRING_HOME_MOVIE, STRING_HOME_MUSIC, STRING_HOME_PHOTO, STRING_HOME_EBOOK, STRING_HOME_FM, STRING_HOME_RECORD, STRING_HOME_SETTING }; int32_t init_multi_screen_res(pmulti_screen_ui_t pui, __s16 current_focus) { uint32_t i; //初始化unfocus ICON 资源 for (i = HOME_UNFOCUS_ICON_START; i pui->bmp_uf[i] = dsk_theme_open(multi_screen_uf_icon[i]); if (pui->bmp_uf[i] == NULL) { __wrn("init_multi_screen_res() index:%d open fail\n", i); } } else { pui->bmp_uf[i] = NULL; } } /*focus icon*/ pui->bmp_f[current_focus] = dsk_theme_open(multi_screen_f_icon[current_focus]); //初始化String 资源 for (i = 0; i ...... pui->bmp_uf[i] = dsk_theme_open(multi_screen_uf_icon[i]); ...... /*focus icon*/ pui->bmp_f[current_focus] = dsk_theme_open(multi_screen_f_icon[current_focus]); ...... }

dsk_theme_open()函数就是根据 theme.h 范围内的ID,到 theme.bin找到相应的图片数据。

3.绘制主界面 3.1 draw_multi_screen_icon_coor_rect()函数调用表格 逐级调用函数所在文件desktop_scene_create()livedesk\beetles\sun20iw1_app\apps\multi_screen_home\desktop_scene\desktop_scene.cdesktop_scene_frm_manager_proc()livedesk\beetles\sun20iw1_app\apps\multi_screen_home\desktop_scene\desktop_scene.cdesktop_scene_view_show_all()livedesk\beetles\sun20iw1_app\apps\multi_screen_home\desktop_scene\desktop_scene.cdraw_multi_screen_icon_coor_rect()livedesk\beetles\sun20iw1_app\apps\multi_screen_home\ui\multi_screen_ui.c

draw_multi_screen_icon_coor_rect()用来绘制界面图标,其中 uf_rect_800_480[8] 是指定图标的区域:

draw_multi_screen_icon_coor_rect(self->pui, HOME_UNFOCUS_ICON_START + i, EPDK_FALSE, &uf_rect_800_480[i]);

《livedesk\beetles\sun20iw1_app\apps\multi_screen_home\desktop_scene\desktop_scene.h》部分内容:

static GUI_RECT uf_rect_800_480[MULTI_SCREEN_STRING_MAX] = { {16, 80, 16 + 180, 80 + 142}, {16 + 180 + 16, 80, 16 + 180 + 16 + 180, 80 + 142}, {16 + 180 + 16 + 180 + 16, 80, 16 + 180 + 16 + 180 + 16 + 180, 80 + 142}, {16 + 180 + 16 + 180 + 16 + 180 + 16, 80, 16 + 180 + 16 + 180 + 16 + 180 + 16 + 180, 80 + 142}, {16, 80 + 50 + 142, 16 + 180, 80 + 142 + 50 + 142}, {16 + 180 + 16, 80 + 50 + 142, 16 + 180 + 16 + 180, 80 + 142 + 50 + 142}, {16 + 180 + 16 + 180 + 16, 80 + 50 + 142, 16 + 180 + 16 + 180 + 16 + 180, 80 + 142 + 50 + 142}, {16 + 180 + 16 + 180 + 16 + 180 + 16, 80 + 50 + 142, 16 + 180 + 16 + 180 + 16 + 180 + 16 + 180, 80 + 142 + 50 + 142}, };


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有