全志ARM926 Melis2.0系统的开发指引⑥
- 编写目的
- 9. 系统启动流程
- 9.1. Shell 部分
- 9.2.Orange 和 desktop 部分
- 9.3. app_root 加载部分
- 9.4. home 加载部分
- 10. 显示相关知识概述
- 10.1. 总体结构
- 10.2. 显示过程
- 10.3. 显示宽高参数关系
- -. 全志相关工具和资源
- -.1 全志固件镜像修改工具 ImageModify.exe 下载
- -.2 全志固件USB刷机工具 PhoenixSuit 下载
- -.3 全志Melis2.0 用户手册.pdf下载
- -.4 全志melis2.0 sdk源码库下载
编写目的
本文档是全志 Melis2.0 系统的开发指引文档,旨在协助开发者了解和掌握 Melis 系统,快速搭建 Melis系统的开发环境,将 Melis2.0 系统应用到产品开发中。
9. 系统启动流程
系统加载流程:boot0- boot1-kernel(epos.img)-shell
当硬件目标平台上电后,BROM 就会将 BOOT0 装载到 SRAM 中,并从 SRAM 开始执行,将控制权交给 eBoot。
eBoot 的启动流程分为两个阶段:
第一个阶段是 BOOT0 加载 BOOT1,BOOT0 将 BOOT1 装载到 DRAM,在 DRAM 上执行;
第二个阶段是 BOOT1 加载系统内核,BOOT1 将内核装载到 DRAM。
每个阶段分别初始化各自所须的硬件资源,同时也为下一个阶段做好准备工作。本文主要说明从 shell
部分到 home 应用的建立。具体流程如下图:
图57:
下面结合代码进行系统加载流程说明:
9.1. Shell 部分
系统初始化完成之后首先进入 Shell 进行初始化操作(路径:suniv\beetles\ramfs
shell.zgj)。 Shell 部分主要函数是 shellmain()它主要调用三个函数,分别是 Esh_init() 、
Esh_StartUp()、Esh_ReaderLoop()。
Esh_init():主要完成一些必要文件的获取路径,申请资源等操作。
Esh_StartUp():检查并执行 Esh_init()函数获取的 script。(路径:suniv\beetles\ramfs\ startup.esh)
Startup.esh:脚本执行 startx。查看 Esh_builtin.c 文件中定义:shell 命令 startx 调用的是 dostart.c
dostartx.c:__exec_startx()。该函数完成 desktop.mod 和 orange.mod 两个模块的加载和检查。
Esh_ReaderLoop():主要完成 shell 命令读取和执行。等待模块、驱动、窗口等部分安装初始化完成后,
在循环中不断读取串口的调试命令进行处理。可执行的命令均在 Esh_builtin.c 文件中。
9.2.Orange 和 desktop 部分
模块加载:以 desktop.mod 为例,查看 mod_desktop 文件夹下面的 make.cfg 有
TARGET = $(WORKSPACEPATH)/beetles/rootfs/mod/desktop.mod
查看入口代码文件 magic.c 找到初始化接口:在 desktop 模块的 MOpen 函数中加载了 init 模块:
模块加载:查看 init 文件夹下面的 make.cfg 有
TARGET = $(WORKSPACEPATH)/beetles/rootfs/apps/init.axf。
首先查看 magic.c 文件,在 MOpen 函数中创建了一个线程 application_init_process。
Desktop 模块加载完成之后加载 init 模块。Init 模块创建一个应用初始化线程 application_init_process。
线程首先装载必要的驱动,例如音频驱动、按键驱动等。接下来是卡量产的必要准备工作,这里不做过多研究。该线程最重要的三项工作是:
1、创建主管理窗口,用于消息的接受和预处理。该窗口名称为 init_mainwin。关于窗口的分类以及功
能见其他章节。窗口创建时向自身发送 GUI_MSG_CREATE 消息,进行初始化操作。
init_mainwin 消息主管理窗口负责消息预处理,新消息先经过本窗口,收到之后在回调函数
init_mainwin_cb()中进行预处理。在调试阶段可以在这里将经过的消息打印出来,查看消息是否被传递到主消息窗口,之后再一级级向下寻找消息传播路径。
2、在消息循环前在_process_init()函数中加载 app_root 应用和注册钩子函数。钩子函数的作用是从
input 输入子系统中拿消息。
3、启动消息接收和分发服务
9.3. app_root 加载部分
在 applets 文件夹下的 make.cfg 有
TARGET = $(WORKSPACEPATH)/beetles/rootfs/apps/app_root.axf
这正是 inti 部分加载的 app_rootfs.axf 文件。首先创建根管理窗口 APP_ROOT。
首 先 调 用 app_root_wincreat() 函 数 创 建 一 个 管 理 窗 口 , 其 父 窗 口 是 init 创 建 的 根 窗 口
init_mainwin ,名字是 APP_ROOT,并且有一个重要参数 ManWindowProc(管理窗口消息处理过程),注册的回调函数为app_root_win_proc()。父窗口 init_mainwin 发送的消息首先在这里被处理,或者将子窗口的消息发送给父窗口。窗口创建时向自身发送 GUI_MSG_CREATE 消息,进行初始化操作。
app_root_win_proc()函数完成消息处理任务。其中较为重要的是 GUI_MSG_CREATE 和 GUI_MSG_COMMAND以及 GUI_MSG_KEY 三种消息。不需要处理的消息交给默认流程往下分发。
接收到 GUI_MSG_CREATE 进行应用创建。
接收到 GUI_MSG_COMMAND,处理子窗口向父窗口发送来的消息。根据 app 的 ID 进行各个 app 之间的切换。包括资源的关闭打开等。
接收到 GUI_MSG_KEY 进行按键消息处理,完成按键响应,或者直接拦截按键消息。
9.4. home 加载部分
APP_ROOT 的回调函数接收到 GUI_MSG_CREATE 消息,继续进行桌面创建。首先进行内存资源申请,创建子管理窗口 APP_HOME。创建函数为 app_home_create()。Home 管理窗口的名字是 APP_HOME,父管理窗口为APP_ROOT,消息处理回调函数为 app_home_proc()。窗口创建时向自身发送 GUI_MSG_CREATE 消息继续进行初始化操作。
app_home_proc()函数主要完成消息处理任务,其中较为重要的是 GUI_MSG_CREATE 和 GUI_MSG_COMMAND以及 GUI_MSG_KEY 三种消息。不需要处理的消息交给默认流程往下分发。
接收到 GUI_MSG_COMMAND,处理子窗口向本窗口发送的消息。
接收到 GUI_MSG_KEY 进行按键消息处理,完成按键响应,或者直接拦截按键消息。
接收到 GUI_MSG_CREATE 接着完成一系列初始化操作:
其中 app_main_menu_create()创建主菜单图层窗口,申请图层,图层大小与屏幕大小一致。另外创建framewin 窗口依赖在图层窗口之上。framewin 管理窗口为 APP_HOME,回调函数为_main_menu_Proc()创建 framewin 窗口时向自身发送 GUI_MSG_CREATE 和 GUI_MSG_PAINT 消息,进行资源初始化和桌面绘制。
_main_menu_Proc()函数主要完成消息处理任务,其中较为重要的是 GUI_MSG_CREATE 和 GUI_MSG_PAINT以及 GUI_MSG_KEY 三种消息。不需要处理的消息交给默认流程往下分发。
接收到 GUI_MSG_PAINT,绘制桌面内容,有些应用该消息未使用,直接在 GUI_MSG_CREATE 完成绘制。
接收到 GUI_MSG_KEY,进行按键消息处理,完成按键响应。
接收到 GUI_MSG_CREATE,初始化 ui 资源,绘制桌面,激活桌面显示:
至此,应用桌面创建完成。
10. 显示相关知识概述
10.1. 总体结构
应用层:melis 的默认应用名为“beetles”,它是独立于内核的一个应用软件。它通过调用“Orange GUI”和“Display Driver”的各项接口,实现了消息转发,窗口绘制和图像显示。
BSP-Orange :Orange 是基于 Melis 操作系统之上的一套 GUI 系统,支持多任务多图层等操作,给上层提供了丰富的 UI 工具。
BSP-Display_driver: Display 驱动是 Melis 内核对底层硬件接口的封装,屏蔽硬件差异,提供一致的接口给上层。所有的显示相关操作,最终都将依赖于该驱动。
硬件层:真正实现显示的硬件模块。最主要的模块是 DE(display engine)和 TCON。DE 主要的工作是将上层传入的图层数据进行裁剪、格式转换、放大缩小等相关操作,然后将数据输送到 TCON。
10.2. 显示过程
当应用层想要显示一个图层,则需要向驱动层请求一个可用的图层,然后将自己的显示参数(图层模式,数据格式,数据宽高,数据 buf 地址等)设置到图层中,就可以将数据显示到屏幕上。伪代码如下:
在这些参数中要注意 buf 的设置,因为不同格式的数据,其存储方式存在差异。
当显示的数据是 ARGB8888 数据时,其 buf 长度应该是“width * height * 4”,A、R、G、B 各有一份自己的数据,但因为这些数据都是连续交替的存放的,只要数据格式一定,对应数据的位置也是固定的,所以这里只需要给“layer_para.fb.addr[0]”设置地
当显示数据是 YUV 数据时,常常 Y、U、V 数据是分开存储或者 Y 数据和 UV 数据是分开存储的,所以可能会 存 在 多 个 buf 地 址 的 情 况 , 这 时 就 要 用 到 “ layer_para.fb.addr[0] ” 、 “ layer_para.fb.addr[1] ” 、“layer_para.fb.addr[2]”参数配合使用。设置好地址后,DE 会自动将 BUF 合并,然后将图层传送到 Tcon 中。
10.3. 显示宽高参数关系
各个宽高参数间有对应的关系。宽高和位置的设置,主要是为了灵活地显示一张图片中的内容。当只需要显示一张图片的某个部分、或者仅将图片在屏幕的某个位置上显示时,就需要对各个宽高进行特定配置。传入参数中的图层 buf,我们可以认定为这是一整张图片,称这个 buf 为“frame buffer”,其宽高为“layer_para.fb.size.width ”和“layer_para.fb.size.height”,而我们可以设置一个窗口,让我 们 在 显 示 过 程 中 , 仅 显 示 窗 口 中 的 内 容 , 这 个 窗 口 从 ( layer_para.src_win.x ,
layer_para.src_win.y ) 坐 标 开 始 , 显 示 宽 为 “layer_para.src_win.width ” 、 高 为
“layer_para.src_win.height”的内容。这里可以看出,“src_win”的宽高必须要比“fb.size”的宽高小
或者相等,且坐标也不能越界,否则显示是不正常的。
当截取到一个窗口后,这个窗口的数据将铺满“SCN”(显示窗口),“src_win”和“scn_win”
的比值,将是这个窗口被拉伸缩小的倍数,当然,最好不要设置比较奇怪的比值(一般的比值
都是 1、2、1/2)否则将会让显示不成功,或者显示不正常。
最后,显示窗口“scn_win”将从(scn_win.x ,scn_win.y)点开始在屏幕上显示,显示宽为
“scn_win.width”,高为“scn_win.height”的图层。
-. 全志相关工具和资源
-.1 全志固件镜像修改工具 ImageModify.exe 下载
下载地址:
固件镜像修改工具 ImageModify.exe下载 ImageModify_20230906.rar
-.2 全志固件USB刷机工具 PhoenixSuit 下载
下载地址:
USB刷机工具 PhoenixSuit下载 PhoenixSuit_CN_V1.1.1_20230906.rar
-.3 全志Melis2.0 用户手册.pdf下载
下载地址:
全志Melis2.0 用户手册.pdf下载 documents_20230906_melis_v2.0.rar
-.4 全志melis2.0 sdk源码库下载
下载地址:
全志melis2.0 sdk源码库下载 melis2.0-sdk-release_20230906V2.0.rar