全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库

全志F1C200S ARM926 Melis2.0系统的开发指引相关工具文档及SDK源码库

  • 1. 编写目的
  • 2. Melis2.0 系统概述
  • 3. Melis2.0 快速开发
    • 3.1. Melis2.0 SDK 目录结构
    • 3.2. Melis2.0 编译环境
    • 3.3. Melis2.0 固件打包
    • 3.4. Melis2.0 固件烧录
    • 3.5.串口打印信息
    • 3.6. Melis2.0 添加和调用一个模块
      • 3.6.1. 为什么划分模块?
      • 3.6.2. UART 驱动模块
        • 3.6.2.1.编译
        • 3.6.2.2.加载和使用
        • 3.6.2.3.UART0 的 PIN 脚配置
  • 4. 编译工具链使用
    • 4.1.工具链通用配置
    • 4.2.模块的工具链配置
    • 4.3.简单的 makefile
  • 5. 固件烧录工具的安装
    • 5.1.PhoenixSuit 的安装步骤
    • 5.2.检验 USB 驱动安装
    • 5.3.使用烧录软件 PhoenixSuit
  • 6. 存储系统简介
    • 6.1.概要描述
    • 6.2.文件系统接口
      • 6.2.1. 文件系统支持
      • 6.2.2. 文件系统接口函数
    • 6.3. Flash 分区
      • 6.3.1.如何配置可配分区的大小
    • 6.4.存储介质开发
      • 6.4.1. NOR Flash
        • 6.4.1.1.添加新 Nor Flash
        • 6.4.1.2.Nor Flash 保存用户数据
      • 6.4.2. SDMMC Card
  • 7. 固件打包脚本
    • 7.1.概要描述
    • 7.2.术语定义
      • 7.2.1. makefile
      • 7.2.2. image.bat
    • 7.3.工具介绍
    • 7.4.打包步骤
      • 7.4.1. makefile 部分
      • 7.4.2. image.bat 部分
    • 7.5.问题与解决方案
      • 7.5.1. 固件由那些文件构成
      • 7.5.2. melis100.fex 文件包含什么内容
      • 7.5.3. ramdisk.iso
      • 7.5.4. udisk.iso
      • 7.5.5. 如何对 sysdata 分区进行添加
      • 7.5.6. 分区对齐设置
      • 7.5.7. 固件烧录后打印提示 spinor 不支持
  • 8. 固件修改工具(ImageModify)使用
    • 8.1.界面说明
    • 8.2.操作步骤
      • 8.2.1. 配置平台
      • 8.2.2. 选择固件
      • 8.2.3. 选择要替换的文件
      • 8.2.4. 替换文件
      • 8.2.5. 保存固件
    • 8.3.注意事项
    • 8.4.增加固件修改权限设置
      • 8.4.1. 概述
      • 8.4.2. 操作说明
        • 8.4.2.1.打包
        • 8.4.2.2.modifycfg.fex 文件编辑说明
  • 9. 系统启动流程
    • 9.1. Shell 部分
    • 9.2.Orange 和 desktop 部分
    • 9.3. app_root 加载部分
    • 9.4. home 加载部分
  • 10. 显示相关知识概述
    • 10.1. 总体结构
    • 10.2. 显示过程
    • 10.3. 显示宽高参数关系
  • 11. 调屏
    • 11.1. 调屏步骤简介
      • 11.1.1. 判断屏接口。
      • 11.1.2. 确定硬件连接。
      • 11.1.3. 配置显示部分 sys_config.fex
        • 11.1.3.1. 配置屏相关 IO
      • 11.1.4. Lcd_panel_cfg.c 初始化文件中配置屏参数
        • 11.1.4.1. LCD_cfg_panel_info
        • 11.1.4.2. LCD_open_flow
    • 11.2. 软件配置说明
      • 11.2.1. 屏文件说明
      • 11.2.2. 开关屏流程
        • 11.2.2.1. 开关屏步骤函数说明
        • 11.2.2.2. 开关屏流程函数说明
      • 11.2.3. 对屏的初始化
        • 11.2.3.1. IO 模拟串行接口初始化
        • 11.2.3.2. CPU 屏 8080 总线初始化
      • 11.2.4. 其它函数
        • 11.2.4.1. GPIO 操作函数
        • 11.2.4.2. 延时函数
    • 11.3. TCON 参数说明
      • 11.3.1. 接口参数说明
        • 11.3.1.1. lcd_if
        • 11.3.1.2. lcd_hv_if
        • 11.3.1.3. lcd_hv_smode
        • 11.3.1.4. lcd_hv_s888_if
        • 11.3.1.5. lcd_hv_syuv_if
        • 11.3.1.6. lcd_cpu_if
        • 11.3.1.7. lcd_lvds_bitwidth
        • 11.3.1.8. lcd_lvds_mode
      • 11.3.2. 时序参数说明
        • 11.3.2.1. lcd_x
        • 11.3.2.2. lcd_y
        • 11.3.2.3. lcd_ht
        • 11.3.2.4. lcd_hbp
        • 11.3.2.5. lcd_vt
        • 11.3.2.6. lcd_vbp
        • 11.3.2.7. lcd_hv_hspw
        • 11.3.2.8. lcd_hv_vspw
        • 11.3.2.9. lcd_dclk_freq
        • 11.3.2.10. lcd_io_cfg0
      • 11.3.3. 其他参数说明
        • 11.3.3.1. lcd_pwm_freq
        • 11.3.3.2. lcd_gamma_correction_en
        • 11.3.3.3. lcd_gamma_tbl
    • 11.4. 屏文件实例
  • 12. 应用程序开发
    • 12.1. APP framework 体系结构
      • 12.1.1. APP framework 简介
    • 12.2. DESKTOP
      • 12.2.1. desktop 简介
    • 12.3. GUI 窗口体系和消息机制
      • 12.3.1. 窗口类型
      • 12.3.2. 消息机制
    • 12.4. 资源使用
      • 12.4.1. 应用字符串资源
        • 12.4.1.1. 制作字符串资源
        • 12.4.1.2. 使用字符串资源
      • 12.4.2. 应用图片资源
        • 12.4.2.1. 制作应用图片资源
        • 12.4.2.2. 使用应用图片资源
      • 12.4.3. 背景图资源
      • 12.4.4. 启动图资源
      • 12.4.5. 按键音资源
      • 12.4.6. 系统功能资源
        • 12.4.6.1. headbar 标题栏
        • 12.4.6.2. background 背景
    • 12.5. 应用程序编写
      • 12.5.1. 简单应用编写
        • 12.5.1.1. 注册应用
        • 12.5.1.2. 创建管理窗口
        • 12.5.1.3. 实现管理窗口消息处理回调函数
        • 12.5.1.4. 创建图层
        • 12.5.1.5. 创建 framewin
        • 12.5.1.6. 实现 framewin 消息处理回调函数
  • 13. 全志相关工具和资源
    • 13.1 全志固件镜像修改工具 ImageModify.exe 下载
    • 13.2 全志固件USB刷机工具 PhoenixSuit 下载
    • 13.3 全志Melis2.0 用户手册.pdf下载
    • 13.4 全志melis2.0 sdk源码库下载

1. 编写目的

本文档是全志 Melis2.0 系统的开发指引文档,旨在协助开发者了解和掌握 Melis 系统,快速搭建 Melis系统的开发环境,将 Melis2.0 系统应用到产品开发中。

2. Melis2.0 系统概述

Melis2.0 系统是基于全志芯片平台自主研发的一套软件系统,其内容涵盖 SDK 代码包、资源制作工具组、编译链接脚本、固件打包烧录工具套件、调试工具 5 个部分,本文档将在后续章节向开发者逐一进行
介绍。
图1:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第1张图片

3. Melis2.0 快速开发

3.1. Melis2.0 SDK 目录结构

Melis2.0 发布版本的 SDK 目录结构如下【图 2】所示,下面按照源码文件夹、打包文件夹、临时库文
件夹、工具文件夹的顺序介绍各文件夹的功能,使开发者对 Melis2.0 SDK 的目录结构有一个初步印象。
图2:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第2张图片

eBSP】板级支持包文件夹,该文件夹存放的是 spi、uart、sdio 等驱动的源码文件,包含了各驱动模块对应寄存器的设置代码,生成的目标文件是.a 后缀的库文件,在编译链接 eMod 中的驱动时使用这些.a 库。

eLIBs】公共库文件夹,生成的目标文件是.a 后缀的库文件,包含了一些公共库函数接口,例如一些本平台自定义的 stdio、string 等接口。

eMod】驱动模块文件夹,本文件夹主要是以 drv_、mod_开头的子文件夹,各子文件夹代表一个独立的驱动/中间件模块,编译每个子文件夹中的源码会生成一个 ELF 格式的可执行文件。eBSP 库中生成的.a 库大多是在这里的驱动模块编译链接时使用。

includes】此文件夹用于存放公用的.h 后缀头文件,为使代码结构清晰,这些头文件会按照功能分别放到各个子文件夹中。

interinc】此文件夹存放的头文件主要是与 ELF 格式可执行文件的解析相关的宏定义和结构体定义等。

livedesk】本文件夹属于应用层文件夹,桌面、音乐、视频、相册、日历、录音等功能的代码均存放于此。

makefile】SDK 根目录编译脚本文件,打开 cygwin 命令行窗口,进入 SDK 目录,输入 make clean;make命令后按“回车”键,就会执行此 makefile 脚本把整个 SDK 重新编译一遍。

workspace】编译 eMod、livedesk 文件夹中的源码所生成的驱动、中间件、应用等独立模块的 ELF 可执行文件均存放于此,通过运行 workspace\suniv\beetles\image.bat 脚本,将这些独立的可执行文件,打包合成一个.img 后缀的文件,用于烧录到开发板中的存储设备(比如 Norflash)。

libs】本文件夹主要是存放.a 库,不存放源码,eBSP、eLIBs 文件夹中编译生成的.a 后缀文件均存放在本文件夹中;

softwares】本文件夹用于存放工具软件。

tools】本文件夹主要存放打包脚本中调用到的 windows 应用程序,例如将一些配置信息更新到已经生成的可执行文件中,就会使用到本文件夹中的工具。

3.2. Melis2.0 编译环境

Melis2.0 的编译环境是 Cygwin + RVDS2.2。
Cygwin 是在 windows 上运行的类 Unix 环境;RVDS2.2 即 RealView Development Suite 2.2,是由 ARM公司出品的交叉编译工具套件。
双击 cygwin 图标运行 cygwin,通过命令行窗口输入命令。进入 SDK 根目录,输入 make clean;make命令来执行根目录的 makefile 脚本,重新编译整个 sdk,参考下【图 3】。可使用文本编辑工具打开 makefile
文件查看和修改。
根目录下的 makefile 脚本运行时,逐层编译链接 eBSP、eLIBs、eMOD、livedesk 文件夹中各个子目
录 , 生 成 ELF 格 式 的 可 执 行 文 件 以 供 打 包 生 成 固 件 。 这 些 ELF 可 执 行 文 件 的 分 别 存 放 到 了
workspace/beetles/ramfs 或 workspace/beetles/rootfs 文件夹。
关于 Melis2.0 编译链接工具的具体调用流程,请参考第 4 章《编译工具链使用》。
图3:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第3张图片

3.3. Melis2.0 固件打包

进入 SDK 的 workspace\suniv\beetles\文件夹,双击 image.bat 运行该脚本,把各驱动、中间件、应
用模块等独立的可执行文件合成到 ePDKv100.img 镜像文件,以便 PhoenixSuit 烧录工具烧录到开发板的Norflash 中。
image.bat 脚本的具体运行流程,可通过文本编辑工具打开查阅和修改,如【图 4】。
图4:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第4张图片

3.4. Melis2.0 固件烧录

Melis2.0 使用的烧录工具是 PhoenixSuit,通过该工具将固件烧录到开发板的 Norflash 中,安装
PhoenixSuit 的操作文档请参看章节《固件烧录工具的安装》。下面我们介绍其中一种烧录方法。
【step1】双击 PhoenixSuit 图标运行 PhoenixSuit 软件,点击“一键刷机”选项卡,通过“浏览”按
钮选择想要烧录的固件的存放路径;
【step2】用 USB 链接线把电脑和开发板链接起来;
【step3】短路 Norflash 的 1、2 引脚,上电 1 到 2 秒钟之后即可松开,当烧录软件出现进度条,表明
PhoenixSuit 通过 USB 检测到开发板,之后烧录软件自动完成剩余的烧录工作;
【step4】等待烧录完成,会有弹窗提示烧录成功,表明烧录完成,之后就可重启设备运行新固件。
烧录期间和重启设备后,都可以通过查看开发板的调试串口输出的打印信息来判断软件的运行状态。
图5:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第5张图片

图6:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第6张图片

图7:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第7张图片

3.5.串口打印信息

安装串口工具(例如 SecureCRT)并打开,通过串口线接收 SoC 输出的 UART 串口打印信息,可以对软件的运行状态做判断,参考【图 9】。
UART 串口波特率是 115200bps,串口收发引脚 Rx/Tx 参看 workspace/eFex/sys_config.fex 文件中的uart_debug_port、uart_debug_tx、uart_debug_rx 参数,如【图 8】所示为窗口 1UART port1 的 PA2/PA3
脚。

图8:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第8张图片

图9:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第9张图片

下面简单介绍一下 SecureCRT 的串口使用步骤。
【step1】双击 图标打开 SecureCRT 软件,通过菜单“文件”->“快速链接”,或直接点击工具
栏的“快速链接”按钮 来直接启动快速链接,出现如【图 10】的提示窗口,点击“协议”条目出现下
拉菜单,选择“Serial”。
图10:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第10张图片

【step2】选择 Serial 协议之后,如【图 11】所示,选择指定的串口,把波特率设置成 115200bps,取消流控的勾选项,然后点击“连接”按钮即可。至此串口 SecureCRT 即可用于收发开发板 UART1 串口的数据。
图11:

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第11张图片

3.6. Melis2.0 添加和调用一个模块

3.6.1. 为什么划分模块?

模块在 Melis2.0 中是一个独立的可执行文件,在介绍前文 SDK 文档目录时提到过模块的概念。一个模块在 SDK 中是如何存在的?它的代码组成基本结构如何?它是如何编译生成的?在固件中如何存在?又如何被加载调用?我们接下来介绍一下。
为使 SDK 结构层次清晰,Melis2.0 将内核操作系统、驱动、中间件、应用等区分开来,单独编译链接生成 ELF 可执行文件,方便各模块独立维护。一个模块需要使用时,要先加载其 ELF 可执行文件,才能使用,不使用时,则可以卸载掉。

3.6.2. UART 驱动模块

图12:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第12张图片

例如串口驱动,进入到 eMod/drv_uart 文件夹,可以看到如【图 12】所示的内容。

3.6.2.1.编译

【make.cfg】
1、通过包含 CROSSTOOL.CFG 指定了编译链接工具为 RVDS 以及 RVDS 工具在电脑上的存储路径;
2、通过 INCLUDES 指定了头文件的包含路径;
3、通过 LIBS 指定了库文件的包含路径;
4、通过 TARGET 指定了输出文件的名称和路径;
5、通过 SRCDIRS 指定了本文件夹及最大 3 层深度的子文件夹中所包含的所有文件名列表;
6、通过 LINK_SCT 指定了链接所使用的文件路径;
7、指定了其他编译选项;
【makefile】通过 SRCCS、SRCSS 过滤得到 SRCDIRS 变量所表示的文件名列表中的.c 和.s 后缀文件参与编译连接,通过 cygwin 进入本文件所在路径,输入 make clean;make 后按“Enter”键,就会执行此 makefile脚本,并将 ELF 可执行文件输出到 TARGET 所指定的路径下,默认 TARGET 是 SDK 目录下的workspace\suniv\rootfs\drv\文件夹,客户可按需自行修改。
图13:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第13张图片

3.6.2.2.加载和使用

uart.drv 生成之后,会在打包时一起合入.img 固件烧录到 Norflash 中,要使用运行该驱动,还需要
把该驱动加载到内存中,并注册给系统的设备管理器。
【magic.c】每个模块都有一个 magic.c 文件,本文件定义了一个结构体,需要注意的是“type”和“mif”
元素:
【type】type 是一个无符号单字节变量,emod.h 头文件以宏定义的形式为每个模块分配了独占的
“type”值,uart 按键驱动的 type 值是 EMOD_TYPE_DRV_UART,开发者如果想添加新模块,可自行添加宏定义,但与其他模块的值不可相同。
【mif】mif 表示模块的接口函数结构体,通过 esDEV_Plugin 函数加载驱动的过程中,依次调用
mif.MInit、mif.MOpen、mif.MIoctrl、mif.MClose 函数,完成 uart.drv 文件的加载、初始化、打开、设备注册和关闭。至此,开发者可通过打开设备注册名所获得的句柄来调用对应的注册函数,下面是一段 UART0驱动使用代码。

图14:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第14张图片

【esDEV_Plugin(“\drv\uart.drv”, 0, NULL, 0)】:如上文所属会根据"\drv\uart.drv"加载固件中
的 uart.drv 驱动到内存,然后调用 mif.init、mif.open、mif.ioctrol、mif.close 接口,在本串口驱动
中则对应的是 DRV_UART_MInit、DRV_UART_MOpen、DRV_UART_MIoctrl、DRV_UART_MClose。需要注意的是函数 DRV_UART_MIoctrl(__mp *mp, __u32 cmd, __s32 aux, void *pbuffer)在这个过程中的 4 各参数:
mp:DRV_UART_MOpen 的返回值;
cmd:DRV_CMD_PLUGIN
aux:对应的是 esDEV_Plugin 函数的第二个参数 0;
pbuffer:对应的是 esDEV_Plugin 函数的第三个参数 NULL;
【pfuart0 = eLIBs_fopen(“\BUS\UART0”, 0)】:需要注意的是,参照源码 DRV_UART_MIoctrl 在处理
DRV_CMD_PLUGIN 消息的过程中调用了 esDEV_DevReg 函数,将为类名为“BUS”、设备名为“UART0”的设备及其接口函数结构体变量 uart_devop 一同注册到内核中。为使 eLIBs_fioctrl 这个接口映射成uart_devop.Ioctl 接口,需要先通过 eLIBs_fopen 接口打开“\BUS\UART0”获得句柄,再将句柄传递给eLIBs_fioctrl 接口,则此时 eLIBs_fioctrl == uart_devop.Ioctl,传参也一一对应。
eLIBs_fwrite函数也因为pfuart0参数映射成了uart_devop.Write,eLIBs_fclose函数也因为pfuart0
参数映射成了 uart_devop.Close;所以上述示例代码中设置波特率和数据发送的工作的得以实现。
类似的如果调用 eLIBs_fread 附带参数 pfuart0 就会映射成为 uart_devop.Read。

3.6.2.3.UART0 的 PIN 脚配置

考虑到芯片引脚封装、PCBA 成本之类的问题,目前市面上的控制器大多采用了引脚复用的方式来减少芯片管脚的使用,全志平台的芯片也采用了引脚复用的方法。
引脚的配置文件是“sdkroot\workspace\suniv\eFex\sys_config.fex”,uart 部分的配置如【图 14】
所示,uart 驱动代码中的 esCFG_GetKeyValue 函数和 esCFG_GetGPIOSecData 函数会通过字符串传参来搜索下面的键值,需要使用的串口要把 uart_used 设置为 1,并将 IO 和复用功能号配置正确。本章侧重于讲解模块的加载和使用以及为配合 UART 测试所涉及到的内容,所以对 sys_config.fex 和 GPIO 不在此详述,相关内容可参考《Melis2.0 文档使用指南.xlsx》
图15:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第15张图片

4. 编译工具链使用

4.1.工具链通用配置

Melis2.0 平台工具链的配置文件是“sdkroot\includes\cfgs\CROSSTOOL.CFG”。 该文件指定了
Melis2.0 平台的编译工具、硬件平台、共用库目录和相关工具的路径,SDK 中所有模块的 makefile 都会引用该配置。
该配置文件中各变量名由平台整合人员统一设置分配,用户可以使用相关的变量,但是不要对变量的
名称作修改,以免造成无法编译。相关变量的含义如下:
$(CROSSTOOL),定义交叉编译工具类型:
“ARMRVDS”,定义交叉编译工具为 RVDS;
“ARMGCC”,定义交叉编译工具为 ARMGCC;

$(EPDK_CHIP),定义硬件平台的类型,定义在脚本“sdkroot\includes\cfgs\chip.cfg”中:
$(LIBPATH),定义 Melis2.0 平台的共享库目录。
$(INTERLIBPATH),定义 Melis2.0 平台内部共享库目录。
$(WORKSPACEPATH),定义 Melis2.0 平台目标文件及打包工作路径。
$(ESTUDIOROOT),定义 Melis2.0 平台使用的 PC 工具的路径。
$(RVDSPATH),定义了 Melis2.0 平台使用的 RVDS 工具的安装路径。
$(CC),定义 C 语言编译工具:
RVDS 交叉编译工具下为“armcc”;
GCC 交叉编译工具下为“arm-elf-gcc”;

$(CFLAGS),定义 C 语言编译工具的基本配置参数。
$(AS),定义汇编器工具:
RVDS 交叉编译工具下为“armasm”;
GCC 交叉编译工具下为“arm-elf-as”;

$(ASFLAGS),定义汇编器的基本配置参数。
$(LINK),定义链接工具:
RVDS 交叉编译工具下为“armlink”;
GCC 交叉编译工具下为“arm-elf-ld”;

$(LKFLAGS),定义链接工具基本配置参数。
$(AR),定义库打包工具:
RVDS 交叉编译工具下为“armar”;
GCC 交叉编译工具下为“arm-elf-ar”;

$(ARFLAGS),定义库打包工具的基本配置参数。
$(LOAD),定义加载器工具:
RVDS 交叉编译工具下为“fromelf”;
GCC 交叉编译工具下为“arm-elf-objcopy”;

$(LDFLAGS),定义加载器工具的基本配置参数。

4.2.模块的工具链配置

CROSSTOOL.CFG 仅配置了一些公共内容,在模块的 make.cfg 使用 include 关键字来使用 CROSSTOOL.CFG
中的配置。包含了公有配置的同时,可在每个模块的 make.cfg 文件中自定义私有配置。虽然是私有配置,但一般都包括下面几个部分:
$(ROOT),定义当前模块的根目录,一般为“.”。
( S D K R O O T ) ,定义“ s d k r o o t ”目录相对于 (SDKROOT),定义“sdkroot”目录相对于 (SDKROOT),定义sdkroot目录相对于(ROOT)的相对路径,此变量必须定义,CROSSTOOL.CFG 配置
文件中会通过此变量来引用 SDK 的根目录。
include $(SDKROOT)/includes/cfgs/CROSSTOOL.CFG,引用编译工具通用配置。
$(INCLUDES),定义所有需要引用的头文件的路径。
$(LIBS),定义需要引用的库文件。
$(SRCDIRS),定义所有需要引用的源文件的路径,一般采用自动扫描的方式来定义,不需要逐项列出。
$(TARGET),定义需要输送出去的目标文件,一般不包含调试信息。
$(LOCALTARGET),定义本地生成的目标文件,一般命名为“__image.axf”,包含有完整的调试信息,用作调试。
$(LINK_SCT),定义链接程序使用的链接脚本。
除此以外,还需要对“CFLAGS”、“ASFLAGS”、“LKFLAGS”、“LDFLAGS”等相关工具配置参数做相应的扩展,以满足模块编译的特定需求。
下面是一个 make.cfg 示例:
图16:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第16张图片

4.3.简单的 makefile

Melis2.0 平台采用 makefile 的隐含规则完成对所有源文件的编译。没有启用完整的依赖规则,只有当
源码文件(.c、.s)文件发生修改后,才会重新编译该源码文件(未修改的源码文件不会被重新编译),修改头文件(.h)不会引发对源码文件的重新编译,因此,当修改了相关的头文件以后,必须先执行 clean,
再重新编译。一个基本的 makefile 一般包括以下几个部分:
include make.cfg,引用 makefile 的配置文件。
$(SRCCS),通过自动扫描获得的
.c 源文件列表。
$(SRCSS),通过自动扫描获得的*.s 源文件列表。
( O B J S ) ,通过后缀替换规则从 (OBJS),通过后缀替换规则从 (OBJS),通过后缀替换规则从(SRCCS)和 ( S R C S S ) 获得的 ∗ . o 文件列表, ∗ . o 文件通过 m a k e f i l e 的隐含规则自动编译 (SRCSS)获得的*.o 文件列表,*.o 文件通过 makefile 的隐含规则自动编译 (SRCSS)获得的.o文件列表,.o文件通过makefile的隐含规则自动编译(SRCCS)和$(SRCSS)获得。
( L O C A L T A R G E T ) : (LOCALTARGET): (LOCALTARGET):(OBJS),链接相关的*.o 和库文件得到本地目标文件。
all:$(LOCALTARGET),通过本地文件得到输出目标文件,该符号也是 makefile 的默认入口。
clean,清理生成的临时文件。
一个简单的 makefile 示例文件如下:
图17:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第17张图片

5. 固件烧录工具的安装

5.1.PhoenixSuit 的安装步骤

【step1】双击 图标,开始 PhoenixSuit 的安装。如【图 18】所示,点击安装向导“下一步”按钮,。
图18:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第18张图片

【step2】如【图 19】所示,默认安装路径,也可点击“浏览”按钮自定义安装路径,点击“下一步”按钮;
图19:

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第19张图片
【step3】如【图 20】所示,点击“下一步”按钮确认安装;
图20:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第20张图片
【step4】如【图 21】所示,进入安装,进度条显示安装进度;
图21:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第21张图片
【step5】如【图 22】所示,安装过程中会弹出 USB 驱动安装提示窗口,点击“下一步”继续安装;
图22:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第22张图片
【step6】如【图 23】所示,如弹出无法验证发布者按钮,请点击“始终安装此驱动程序软件”继续安装;
图23:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第23张图片
【step7】如【图 24】所示,驱动安装完成后弹出提示窗口,点击“完成”按钮结束 USB 驱动的安装;
图24:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第24张图片
【step8】如【图 25】所示,【step7】的 USB 驱动的安装完成后,PhoenixSuit 会继续自动安装,安装完成后会出现“安装完成”提示窗口,点击“关闭”按钮结束安装。
图25:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第25张图片

5.2.检验 USB 驱动安装

PhoenixSuit 安装完成后,可打开 windows 的“设备驱动管理器”,点击“通用串行总线控制器”弹出
的设备条目,查看是否有“VID_1f3a_PID_efe8”的 USB 设备,如【图 26】所示。
图26:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第26张图片
如果开发者想要重新安装驱动,驱动在 PhoenixSuit 的安装文件夹中也有备份,参考下图【图 27】所示。
图27:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第27张图片

5.3.使用烧录软件 PhoenixSuit

【step1】双击 图标,运行 PhoenixSuit 工具,点击“一键刷机”选项卡,如【图 28】所示
图28:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第28张图片
【step2】点击【图 11】的“浏览”按钮来指定固件的存放路径,参考【图 29】,选中.img 后缀的固件文件之后,点击“打开”按钮完成固件选择。
图29:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第29张图片
【step4】选择好固件之后如【图 30】所示。接下来参考【图 31】,开发板断电的情况下,短路 Norflash 的1、2 引脚,通过 USB 线将电脑和开发板相连,再给开发板上电,上电 1~2 秒后松开 Norflash 的短路引脚即
可。如开发板本身是通过 USB 的 5V 供电,即 USB 链接电脑和开发板时就已经上电,则按照“先短路,后供电”的原则操作本步骤。
图30:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第30张图片

图31:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第31张图片
【step5】步骤 4【step4】完成之后,开发板就会跟电脑交互通信,自动进入烧录模式,PhoenixSuit 出现进度条提示烧录进度,如【图 32】所示。至此,开发者等待烧录完成即可。
图32:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第32张图片
【step6】烧录完成后,会出弹出烧录成功提示窗口,则表示烧录成功完成,开发者即可重启运行新固件。
图33:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第33张图片

6. 存储系统简介

6.1.概要描述

此文档主要介绍 Melis 2.0 的存储开发方法。与固件结构组成等。

6.2.文件系统接口

6.2.1. 文件系统支持

Melis2.0 支持可读写的文件系统分别是:fat exfat ntfs。支持只读文件系统 udf。(其中 melis 还支持全志自主研发的 minfs 文件系统,但上层不会使用)

6.2.2. 文件系统接口函数

图34:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第34张图片
melis 系统文件更多相关接口在 elibs_stdio.c 文件。此处就不一一列举了。

6.3. Flash 分区

Melis flash 固件通常共分为 5 个分区,分别为:BOOT0、BOOT1、MBR、ROOTFS、UDISK
BOOT0:boot0 的具体工作是先进行初始化处理器,icache,UART,定时器,JTAG,DRAM 和 HEAP 等操作,然后再将 boot1 装载进 DRAM。
BOOT1:boot1 主要负责装载系统内核、强制升级检测、调试开关和 boot_logo 的数据加载。除此之外,还需要进行内存管理,调频,初始化相关硬件。
MBR:主引导记录,记录分区信息。
ROOTFS:主要存放内核(epos.img)与各种驱动文件。
UDISK:保存系统运行过程中需要保存的用户数据,包括音量、语言设置、音视频端点信息等。如其中setting.bin 文件。
SYSDATAFS:此分区默认未分配,需要使用需要自己添加,该分区主要存储用户自定义数据。
图35:
在这里插入图片描述

6.3.1.如何配置可配分区的大小

分区大小的配置。其中 BOOT0,BOOT1,MBR 三个分区已经固定写死不能修改,可以修改的是 ROOTFS和 UDISK。而 UDISK 分区大小是 NOR Flash 大小减去前面分区分配的容量,剩下的全部默认分配给 UDISK 分区。这两个分区的的配置主要是在 SDK/workspace/suniv/eFex/sys_config.fex 中主键 part_num,和 partition0。
如下图
图36:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第35张图片
如上图所示,修改 ROOTFS 分区需要修改步骤如下

  1. 修改 sys_config.fex 文件的主键 partition0,子健 size_lo 的值,单位为 Kbyte。
  2. 修改 SDK/workspace/suniv/beetles 路径下的 rootfs.ini 文件中的主键[IMAGE_CFG],子键 size 的大小,需要和第一步配置的大小一致。
    图37:
    全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第36张图片
  3. 计算出 udisk 分区大小,总容量-BOOT0-BOOT1-ROOTFS。即 8192K- 24K- 120K- 1K- 7919K =128K。将该值填入 SDK/workspace/suniv/beetles 路径下的 udisk.ini 文件中的主键[IMAGE_CFG],子键 size。
    图38:
    全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第37张图片
  4. 重新打包生成固件。即完成 rootfs 和 udisk 分区的大小修改。

6.4.存储介质开发

6.4.1. NOR Flash

NOR Flash 暂不支持根据物料信息来适配物料读写命令模式,目前是固定使用双线读,单线写的模式。

6.4.1.1.添加新 Nor Flash

在 sys_config.fex 添加新物料,如下所示:
图39:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第38张图片
除了在 sys_config.fex 添加新物料。还可以在代码里面添加新物料参数。
NOR Flash 驱动核心代码位于 eMod/drv_storages/spinor/spinor_drv/hal_spinor.c 中,需增加对新
物料的支持,可以在 spinor_info_set[] 数组中新增物料信息,如物料名称,jedec id,擦除块大小,容量等。不过在此处添加物料信息,如果物料不是 8MBit,在此处添加物料信息,有可能会出现烧录失败的现象,因此建议通过 sysconfig.fex 中添加新物料。

6.4.1.2.Nor Flash 保存用户数据

系统挂载的 udisk 和 sysdatafs 分区,当应用对这两个分区进行读写操作时,只是对内存数据进行操作,flash 里面数据时不会被修改,如果需要将修改的数据写进 flash 里,需要调用刷 flash 的接口。两个分区的保存流程接口是一样的,但参数存在一点差异,具体流程这里就不赘述,详情参考<<用户数据保存>>。

6.4.2. SDMMC Card

SDK 里面提供了两个 sdmmc 的驱动,sdmmc1 和 sdmmc2。其中 sdmmc 是对应我们平常 norflash 启动后插入的 sd 卡的驱动。sdmmc2 是对应卡启动的卡驱动。

7. 固件打包脚本

7.1.概要描述

打包固件是下载前的最后一步。系统应用程序、驱动编写完成,经过编译得到输出文件,加上各种中
间件、资源文件、配置文件、系统内核等统一打包生成固件,固件下载到开发板上就可以运行了。在 melis2.0中,是利用批处理 image.bat 进行打包操作。打包主要工作有三方面。一方面在生成的各种源文件中拷贝需要的文件到打包路径下,第二方面利用更新工具对源文件进行更新,第三方面根据配置文件将源文件按照一定规则进行打包操作,最终生成可以烧录的固件。

7.2.术语定义

7.2.1. makefile

makefile 是自动化编译脚本。makefile 文件描述了工程的编译和连接规则。包括工程中那些源文件需
要编译以及如何编译、需要调用那些库文件,设置最后生成文件的路径等等。每个应用程序、模块等工作目录都有几个特定文件,包括 makefile magic.c make.cfg。Magic.c 是模块、驱动的入口,具有统一形式。
Make.cfg 是配置文件,目前主要关注的是 target,它指明源文件生成路径以及生成文件的名字。

7.2.2. image.bat

bat 批处理文件是一系列 dos 命令的集合。文件的每一行都是一条 dos 命令。将特定命令编写完成运行就可以简化日常或重复性的任务。Image.bat 文件是打包批处理文件,运行它就可以生成最新的固件。

7.3.工具介绍

1、update_boot 工具:update_boot 会根据配置文件,修正 boot 中的参数。
2、BurnMBR 工具:BurnMBR 工具主要是用来生成 MBR 数据,其输出文件为 mbr.bin。
3、minfs 工具:制作 minfs 分区。
4、fsbuild 工具:fsbuild 工具用于制作 fat16 文件系统。
5、fix_file 工具:fix_file 工具较为简单,只是将输入文件延长为指定长度的输出文件,其中的延
长部分是 0。
6、dragon 工具:打包。

7.4.打包步骤

7.4.1. makefile 部分

首先对整个工程进行编译,生成源文件。在 cygwin 环境下在工程根目录使用 make clean;make 命令对整个工程进行编译(如果只修改其中一些部分可以只编译修改部分)。Makefile 会将各部分生成文件分类存放到指定路径。本工程生成路径是 ROOT\c500_net_theater\workspace\suniv。

7.4.2. image.bat 部分

固件打包的工作路径是 ROOT\c500_net_theater\workspace\suniv\beetles。打包固件以前,要确认配
置文件正确,并且 makefile 生成的源文件是最新的。
Image.cfg 是配置文件,它指定了那些文件需要打包到固件中,设置固件名字、版本等信息。在生成的image.txt 文件中可以看到各个被打包文件的信息,包括大小、路径、主键、子键等信息。
Image.bat 的工作流程如下:
1、首先进行一些初始化操作。将原有的镜像删除,设置打包工具路径等。
2、运行 update.bat 批处理文件。查看生成的 update.txt 文件,update.bat 主要是完成文件复制操作,将需要使用的文件按照分类存放到打包路径待用。
3、使用打包工具解析脚本文件(.fex 文件)、更新 boot0 和 boot1 文件头、生成 MBR 文件、更新 fes1、uboot 文件头。如 Boot 阶段使用的__boot0_file_header_t 结构体,在本阶段使用脚本文件更新部分参数,包括 dram、uart、jtag_para、spi 参数等。
4、根据配置文件,生成 MBR 文件,大小为 1kb。
5、更新 usb 烧录文件,根据系统配置文件 sys_config.fex 来修正 fes1 和 uboot 的各项参数。
6、生成文件系统镜像,运行 fsbuild.bat。根据 rootfs.ini、ramfs.ini、udisk.ini 文件将需要的文
件进行打包,分别生成 rootfs.iso、ramfs.iso、udisk.iso。根据不同的命令制作 rootfs.iso、ramfs.iso
两个 minfs 文件系统镜像,和 udisk.iso 的 fat 文件系统镜像。
7、对 boot0 和 boot1 的文件大小进行填充 boot0 为 24kb,boot1 为 120kb。
8、将 boot0.bin boot1.bin mbr.bin rootfs.iso udisk.iso 连接打包成为 melis100.fex 文件,并且
生成校验文件 verify.fex。
9、运行 deagon 工具,根据配置信息 image.cfg 生成镜像包文件 ePDKv100.img。
10、删除清理临时文件,可以在脚本中用#注释掉一些删除,观察临时文件的大小是否符合预期。

7.5.问题与解决方案

7.5.1. 固件由那些文件构成

固件由资源文件、配置文件、系统内核、应用程序、驱动、中间件构成。

7.5.2. melis100.fex 文件包含什么内容

以 8M 固件系统未加载 sysdata 分区为例,melis100.fex 是在 do_checksum()中生成的。melis100.fex 是固件里面的重要内容,包含了 boot0.bin boot1.bin mbr.bin rootfs.iso udisk.iso 共计 5 个部分。其中 boot0大小为 24KB,boot1 大小为 120KB,MBR 大小为 1KB,这三部分固定不变,同时 boot 部分都预留空间,保留。
Rootfs 部分为 7919KB,udisk 部分为 128KB。整个文件大小为 8192KB。具体模型如下图:
图40:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第39张图片

7.5.3. ramdisk.iso

Ramdisk 在系统启动阶段提供帮助。系统启动时需要挂载根文件系统,根文件系统包含了各种驱动和模块和各种源文件(内核是精简的,不可能把所有的驱动和模块编译进内核,这会让内核很大)。问题就在于挂载根文件系统却需要根文件系统上面的驱动和模块,这是相互矛盾的问题。Ramdisk 包含了系统启动必要的驱动和模块,在启动阶段 ramdisk 和内核都被预先加载到内存中,再通过 ramdisk 里边的驱动和模块帮助启动系统,最终挂载根文件系统。

7.5.4. udisk.iso

Udisk 保存系统运行过程中需要保存的用户数据,包括音量、语言设置等信息。

7.5.5. 如何对 sysdata 分区进行添加

(1)更新打包工具
更新\tools\build_tools 目录下的 BurnMBR.exe 和 script.exe 工具;
(2) 配置 sysdatafs 盘符,修改分区大小
在 sys_config.fex 文件中按需求添加 sysdatafs 盘符,字符串需带引号””表示才能解析;打包路径下的
sysdata.ini,rootfs.ini,udisk.ini 里 面 的 size 大 小 需 与 配 置 文 件 中 对 应 。 并 且 要 注 意 , 如 果
sys_config.fex 中不存在 UDISK,这个分区,则在工具中会自动加上,所以,当 part_num 为 2 时,总共有
三个分区。
图41:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第40张图片
(3) 创建 sysdatafs.iso 镜像
fsbuild.bat 文件添加如下语句以创建 sysdatafs.iso,大小在 beetles 文件夹下的 sysdatafs.ini 文件中
配置;(注:在第(2)步中定义的分区大小,需要和 ini 后缀文件中定义的大小需一致)
…\tools\build_tools\fsbuild200\fsbuild.exe .\sysdatafs.ini
(4) 添加 sysdatafs.iso 镜像到固件
在打包文件 image.bat 中将 sysdatafs.iso 添加到固件中:
type boot0.bin boot1.bin mbr.bin rootfs.iso sysdatafs.iso udisk.iso > melis100.fex
(5) 更新 spinor.drv 驱动

7.5.6. 分区对齐设置

由问题一可知分区分布情况,其中 sysdata 和 udisk 分区是可读写分区,norfalsh 是必须先将需要写
的区域进行擦除,才能正常进行写操作,而擦除 nor 的操作暂时是以 64K 为单位,因此要求 sysdata 和 udisk分区的起始地址和大小都需要 64K 对齐。(sysdata 和 udisk 分区数据保存请参考文档《用户数据保存》)
当分区未按 64K 对齐时,可能引发用户数据保存失败等未知错误。

7.5.7. 固件烧录后打印提示 spinor 不支持

在首次使用机器烧录固件,或者更换新 NORFLASH 后烧录固件,有可能出现下图打印:
图42:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第41张图片
此时打印提示 spinor 不支持,并且给出了 norflash 的 id为 0x17701c。因此我们需要在 sys_config.fex文件中将该型号的 nor 添加上去,具体如何修改,请参考文件中的说明。完成 norflash 型号的添加后如下图:
图43:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第42张图片

8. 固件修改工具(ImageModify)使用

8.1.界面说明

ImageModify 工具路径为“SDK\softwares\ImageModify”。ImageModify 的作用是通过该工具直接替换
固件内部分文件,生成一个新固件。
主界面如下:
图44:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第43张图片

  1. 选择固件文件按钮

  2. 替换目标的系统盘文件浏览

  3. 选中的文件信息

  4. 替换按钮

  5. 图片浏览区

  6. 进度条

  7. 保存按钮
    注:由于软件版本不同,界面可能存在一点差异。

8.2.操作步骤

8.2.1. 配置平台

在软件运行目录下运行批处理文件 config.bat。此批处理具体作用可参考软件目录下文档《固件修改工具 V300 说明文档》。
图45:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第44张图片
根据平台的类型选择不同的数字,以 C200S 为例子,则选择 5 即可。

8.2.2. 选择固件

在运行目录下启动固件修改工具 ImageModify.exe 或者 ImageModify-not compress logo.exe。
图46:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第45张图片
运行界面如下:
图47:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第46张图片
点击 … ,选择要打开的固件文件。固件打开后有如下界面:
图48:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第47张图片

8.2.3. 选择要替换的文件

固件打开后,在目标替换文件浏览区可以看到该分区下的所有目录和文件,如下图
图49:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第48张图片
点击需要替换的文件:
图50:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第49张图片
在上图可以看到选中的文件

8.2.4. 替换文件

在步骤 3 中选中文件后,点击 Replace 按钮 ,选择新的文件进行替换。
图51:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第50张图片

8.2.5. 保存固件

当替换完所有要替换的文件后,点击按钮 ,等待进度条提示如下:
图52:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第51张图片
表示保存成功。会在打开固件目录下会生成一个.img 的新固件。
图53:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第52张图片

8.3.注意事项

nor 系统的配置脚本要更新一下,参见软件工具目录下“nor 系统配置脚本”文件夹,修改了

  1. update.bat 中增加

@copy .\ramfs.ini .\ramfs\ramfs_ini.tmp
@copy .\rootfs.ini .\rootfs\rootfs_ini.tmp
2. image.bat 文件中增加

del .\ramfs\ramfs_ini.tmp
del .\rootfs\rootfs_ini.tmp
3. beetles\rootfs 里面添加 app_config.fex 文件。可参考修改工具\nor 系统配置脚本下面的修改范例
4. 若 beetles\rootfs 里面 app_config.fex 文件存在则无需添加。app_config.fex 文件内容也有限制,
app_config 里面结构基本是类似于主键和子键的结构形式,如下所示
图54:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第53张图片此处仅为举例,不考虑 client 的实际作用。

[client]
clientid=4C4E
如上例子键等号后面的值如果数字开头不能带有字母,否则在 save 时,会提示如下错误
图55:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第54张图片
子键等号后面的值如果以字母开头或者 0x 开头则可为任意字符串。正常保存生成新固件。如下图:
图56:
在这里插入图片描述

8.4.增加固件修改权限设置

8.4.1. 概述

为了避免用户随意修改或者保护固件修改权限,需要在固件中增加限制修改的方法。通过这种机制,
固件发布者可以设置允许修改的文件列表,进入修改权限的密码等信息。

8.4.2. 操作说明

8.4.2.1.打包

将 modifycfg.fex 文件放在打包路径下,在 image.cfg 文件中的[FILELIST]段中增加如下项

{filename = INPUT_DIR"beetles\modifycfg.fex", maintype = ITEM_COMMON, subtype = “MDF_CONFIG000000”,}, modifycfg.fex 文件是设置修改权限的文件。

8.4.2.2.modifycfg.fex 文件编辑说明

 设置终端客户验证修改权限的密码

Password=“12345”
如果不需要密码,则将该字段设置成 Password=""即可。

 设置一级代理商验证修改权限的密码

xPassword=“12345”
如果不需要密码,则将该字段设置成 Password=""即可。

 设置是否限制

Limited=1
= 1 表示限制,=0 表示全部可以修改

 设置允许修改的文件列表

FilesTab=
{
{File=" \res\boot_ui\logo.bmp"}, {File=" \apps\desktop.bin"}, {File=" \drv"}, --定义 drv 整个目录都可以修改

}

如果整个目录可修改,就定义一个目录名称即可,如例子中的

{File=" \drv"},
备注:
如果是修改 bin 档(非 img 档),那么权限设置功能无法生效,所有文件将可见并可替换。

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:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第55张图片
下面结合代码进行系统加载流程说明:

9.1. Shell 部分

系统初始化完成之后首先进入 Shell 进行初始化操作(路径:suniv\beetles\ramfs
shell.zgj)。 Shell 部分主要函数是 shellmain()它主要调用三个函数,分别是 Esh_init() 、
Esh_StartUp()、Esh_ReaderLoop()。
Esh_init():主要完成一些必要文件的获取路径,申请资源等操作。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第56张图片
Esh_StartUp():检查并执行 Esh_init()函数获取的 script。(路径:suniv\beetles\ramfs\ startup.esh)
在这里插入图片描述
Startup.esh:脚本执行 startx。查看 Esh_builtin.c 文件中定义:shell 命令 startx 调用的是 dostart.c
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第57张图片
dostartx.c:__exec_startx()。该函数完成 desktop.mod 和 orange.mod 两个模块的加载和检查。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第58张图片
Esh_ReaderLoop():主要完成 shell 命令读取和执行。等待模块、驱动、窗口等部分安装初始化完成后,
在循环中不断读取串口的调试命令进行处理。可执行的命令均在 Esh_builtin.c 文件中。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第59张图片

9.2.Orange 和 desktop 部分

模块加载:以 desktop.mod 为例,查看 mod_desktop 文件夹下面的 make.cfg 有
TARGET = $(WORKSPACEPATH)/beetles/rootfs/mod/desktop.mod
查看入口代码文件 magic.c 找到初始化接口:在 desktop 模块的 MOpen 函数中加载了 init 模块:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第60张图片
模块加载:查看 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 输入子系统中拿消息。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第61张图片
3、启动消息接收和分发服务
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第62张图片

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 消息,进行初始化操作。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第63张图片
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 消息继续进行初始化操作。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第64张图片
app_home_proc()函数主要完成消息处理任务,其中较为重要的是 GUI_MSG_CREATE 和 GUI_MSG_COMMAND以及 GUI_MSG_KEY 三种消息。不需要处理的消息交给默认流程往下分发。
接收到 GUI_MSG_COMMAND,处理子窗口向本窗口发送的消息。
接收到 GUI_MSG_KEY 进行按键消息处理,完成按键响应,或者直接拦截按键消息。
接收到 GUI_MSG_CREATE 接着完成一系列初始化操作:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第65张图片
其中 app_main_menu_create()创建主菜单图层窗口,申请图层,图层大小与屏幕大小一致。另外创建framewin 窗口依赖在图层窗口之上。framewin 管理窗口为 APP_HOME,回调函数为_main_menu_Proc()创建 framewin 窗口时向自身发送 GUI_MSG_CREATE 和 GUI_MSG_PAINT 消息,进行资源初始化和桌面绘制。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第66张图片
_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 资源,绘制桌面,激活桌面显示:

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第67张图片
至此,应用桌面创建完成。

10. 显示相关知识概述

10.1. 总体结构

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第68张图片
应用层: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 地址等)设置到图层中,就可以将数据显示到屏幕上。伪代码如下:
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第69张图片
在这些参数中要注意 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. 显示宽高参数关系

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第70张图片
各个宽高参数间有对应的关系。宽高和位置的设置,主要是为了灵活地显示一张图片中的内容。当只需要显示一张图片的某个部分、或者仅将图片在屏幕的某个位置上显示时,就需要对各个宽高进行特定配置。传入参数中的图层 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”的图层。

11. 调屏

11.1. 调屏步骤简介

11.1.1. 判断屏接口。

首先要判断屏的接口,是 HV、CPU 还是 LVDS 接口的屏,不同的接口,硬件连线及调屏方法不一样。
1.询问客户、屏厂或则根据屏的规格书等确定。
2.通过硬件连线方式确定。

11.1.2. 确定硬件连接。

不同的接口屏,硬件连接不一样,同一接口的屏,连接方式有几种。

1.根据“屏硬件连接”确认。

2.根据原理图确认屏背光、电源、时钟、复位及扩展 IO 连接。

11.1.3. 配置显示部分 sys_config.fex

11.1.3.1. 配置屏相关 IO

;---------------------------------------------------------------------------------------------------------
; 说明: 脚本中的字符串区分大小写,用户可以修改"="后面的数值,但是不要修改前面的字符串
; 描述gpio的形式:Port:端口+组内序号<功能分配><内部电阻状态><驱动能力><输出电平状态>
; pinName = port:P[A-J]<CFG><PULL><DRV_LEVEL><DATA>
;---------------------------------------------------------------------------------------------------------
[lcd0_para]
lcd_power_used = 0
lcd_power = port:PA0<1><default><default><1>
lcd_bl_en_used = 0
;lcd_pwm_used = 0
;lcd_pwm = port:PE12<4><0><default><default>
;lcdd0 = port:PE0<3><default><default><default>
....
lcdvsync = port:PD21<2><default><default><default>

11.1.4. Lcd_panel_cfg.c 初始化文件中配置屏参数

11.1.4.1. LCD_cfg_panel_info

lcd_panel_para_info(__s32 sel, disp_panel_para *info) 函数中设置相关屏参,包括像素、刷新
率、前后肩、RGB 格式等。

11.1.4.2. LCD_open_flow

根据屏的开屏流程函数 LCD_open_flow(__u32 sel) 修改相关函数:
1.static void LCD_power_on(__u32 sel)使能屏,设置复位时序。
2.自定义 LCD_panel_init(__u32 sel) 函数根据屏写数据的不同接口,调用相关接口,写入初始化代
码。该函数接在 LCD_power_on 函数之后即可。
比如 hv 屏可能需要 spi 或 iic 初始化,用 LP_TX 模式初始化。无需设置初始化代码的屏,不用设置。

11.2. 软件配置说明

11.2.1. 屏文件说明

lcd_panel_cfg.c 文件,定义了 TCON 的参数,开关屏的流程,还有对屏的初始化操作。
对 IO 位置的定义,包括电源控制,配屏使用的 GPIO,以及 LCD 控制器 IO 的定义在 sys_config.fex 中。
函数:LCD_cfg_panel_info
功能:配置 C200S 的 TCON 基本参数
原型:static void LCD_cfg_panel_info(__panel_para_t * info)
参数的定义见“3 TCON 参数说明”。

函数:LCD_open_flow
功能:定义开屏的流程
原型:static __s32 LCD_open_flow(__u32 sel)
具体说明见“2.2 开关屏流程”。

函数:LCD_close_flow
功能:定义关屏的流程
原型:static __s32 LCD_close_flow(__u32 sel)
该函数与 LCD_open_flow 对应

函数:LCD_get_panel_funs_0/ LCD_get_panel_funs_1
功能:
原型:void LCD_get_panel_funs_0(__lcd_panel_fun_t * fun)
初始化注册屏的相关操作。

11.2.2. 开关屏流程

开关屏的常见操作流程如图 2-2 所示。
其中,LCD_open_flow 和 LCD_close_flow 称为开关屏流程函数,方框中的函数,如 LCD_power_on,

TCON_open 等函数,称为开关屏步骤函数。
部分屏不需要写入屏初始化参数,LCD_panel_init 及 LCD_panel_exit 这两个步骤函数(图中紫色框部分)可以省去。

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第71张图片

11.2.2.1. 开关屏步骤函数说明

开屏的步骤函数有 LCD_panel_init,TCON_open, LCD_power_on,LCD_bl_open。

函数:LCD_panel_init
功能:对屏初始化
原型:static void LCD_panel_init(__u32 sel)
可参考“2.3 对屏的初始化”。部分屏不需要进行初始化操作,LCD_panel_init 及 LCD_panel_exit 这两个步骤函数可以省去。

函数:TCON_open
功能:打开 F20 TCON
原型:__s32 TCON0_open(__u32 sel)
该函数由显示驱动提供,用户无需实现。

函数:LCD_power_on
功能:打开 LCD 电源
原型:static void LCD_power_on(__u32 sel)
显示驱动提供 LCD_POWER_EN 函数可供调用,用户也可自由实现函数内容。

函数:LCD_bl_open
功能:打开 LCD 背光
原型:static void LCD_bl_open(__u32 sel)
显示驱动提供 LCD_PWM_EN 和 LCD_BL_EN 函数可供调用,用户也可自由实现函数内容。
LCD_PWM_EN,LCD_BL_EN,LCD_POWER_EN 这三个函数是通过 GPIO 控制实现电源和背光的开启关闭,IO 的位置及属性定义在 sys_config.fex 文件中。

函数:LCD_PWM_EN
功能:打开或关闭 LCD 背光调节的 PWM 信号
原型:void LCD_PWM_EN (__u32 sel, __bool b_en)
参数说明:
b_en=0:将 PWM pin 设为输入,并把 PWM 模块关闭
b_en=1:将 PWM pin 设为 PWM,并把 PWM 模块打开
对应于 sys_config.fex 文件的 lcd_pwm。

函数:LCD_BL_EN
功能:打开或关闭 LCD 背光
原型:void LCD_BL_EN (__u32 sel, __bool b_en)
参数说明:
b_en=0:设置 LCD 背光控制 IO 为对应电平,关闭背光
b_en=1:设置 LCD 背光控制 IO 为对应电平,打开背光
对应于 sys_config.fex 文件的 lcd_bl_en;

函数: LCD_POWER_EN
功能:打开或关闭 LCD 电源
原型:void LCD_POWER_EN (__u32 sel, __bool b_en)
参数说明:
b_en=0:设置 LCD 电源控制 IO 为对应电平,关闭 LCD 电源
b_en=1:设置 LCD 电源控制 IO 为对应电平,打开 LCD 电源
对应于 sys_config.fex 文件的 lcd_power。
关屏的步骤函数与开屏的步骤函数相对应。

11.2.2.2. 开关屏流程函数说明

函数:LCD_open_flow
功能:初始化开关屏的步骤流程
原型:static __s32 LCD_open_flow(__u32 sel)

函数常用内容为:

static __s32 LCD_open_flow(__u32 sel)
{
    LCD_OPEN_FUNC(sel, LCD_power_on,10);
    LCD_OPEN_FUNC(sel, LCD_panel_init, 50);
    LCD_OPEN_FUNC(sel, TCON_open, 100);
    LCD_OPEN_FUNC(sel, LCD_bl_open, 0);
    return 0;
}

如上,初始化整个开屏的流程步骤为四个:
1、打开 LCD 电源,再延迟 10ms;
2、初始化屏,再延迟 50ms;
3、打开 C200S TCON,再延迟 200ms;
4、打开背光,再延迟 0ms。
LCD_open_flow 函数只会系统初始化的时候调用一次,执行每个 LCD_OPEN_FUNC 即是把对应的开屏步骤函数进行注册,并没有执行该开屏步骤函数。LCD_open_flow 函数的内容必须统一用 LCD_OPEN_FUNC(sel, function, delay_time)进行函数注册的形式,确保正常注册到开屏步骤中。

函数:LCD_OPEN_FUNC
功能:注册开屏步骤函数到开屏流程中
原型:void LCD_OPEN_FUNC(__u32 sel, LCD_FUNC func, __u32 delay)
参数说明:
func 是一个函数指针,其类型是:void (*LCD_FUNC) (__u32 sel),用户自己定义的函数必须也要用统一的形式。比如:

void user_defined_func(__u32 sel)
{
    //do something
    
}

delay 是执行该步骤后,再延迟的时间,时间单位是毫秒。

11.2.3. 对屏的初始化

一部分屏需要进行初始化操作,在开屏步骤函数中,对应于 LCD_panel_init 函数。在 C200S 中,提供了两种方式对屏的初始化。
一种是通过 8080 总线的方式,使用的是 LCDIO(PD,PH)。这种初始化方式,用于 CPU 屏中,其总线的引脚位置定义与 CPU 屏一致。
一种是 SPI 或 IIC 等串行的方式,使用的是 C200S 的 GPIO 引脚模拟实现。模拟 GPIO 的引脚位置定义见于sys_config.fex 中。

11.2.3.1. IO 模拟串行接口初始化

IO 模拟串行接口初始化可以参考附录中的实例。
IO 的位置(PIN 脚)定义,默认属性(输入输出)定义及默认输出值在 sys_config.fex,具体请参考 2.5.2。
显示驱动提供 3 个接口函数可供使用。说明如下:
函数:LCD_GPIO_read
功能:读取 LCD_GPIO PIN 脚上的电平
原型:__s32 LCD_GPIO_read(__u32 sel,__u32 io_index);
参数说明:
io_index = 0:对应于 sys_config.fex 中的 lcd_gpio_0
io_index = 1:对应于 sys_config.fex 中的 lcd_gpio_1
io_index = 2:对应于 sys_config.fex 中的 lcd_gpio_2
io_index = 3:对应于 sys_config.fex 中的 lcd_gpio_3
函数返回值为对应 IO 的输入电平,只用于该 GPIO 定义为输入的情形。

函数:LCD_GPIO_write
功能:LCD_GPIO PIN 脚上输出高电平或低电平
原型:__s32 LCD_GPIO_write(__u32 sel,__u32 io_index, __u32 data);
参数说明:
io_index = 0:对应于 sys_config.fex 中的 lcd_gpio_0
io_index = 1:对应于 sys_config.fex 中的 lcd_gpio_1
io_index = 2:对应于 sys_config.fex 中的 lcd_gpio_2
io_index = 3:对应于 sys_config.fex 中的 lcd_gpio_3
data = 0:对应 IO 输出低电平
data = 1:对应 IO 输出高电平
只用于该 GPIO 定义为输出的情形。

函数:LCD_GPIO_set_attr
功能:设置 LCD_GPIO PIN 脚为输入或输出模式
原型:__s32 LCD_GPIO_set_attr(__u32 sel,__u32 io_index, __bool b_output);
参数说明:
io_index = 0:对应于 sys_config.fex 中的 lcd_gpio_0
io_index = 1:对应于 sys_config.fex 中的 lcd_gpio_1
io_index = 2:对应于 sys_config.fex 中的 lcd_gpio_2
io_index = 3:对应于 sys_config.fex 中的 lcd_gpio_3
b_output = 0:对应 IO 设置为输入
b_output = 1:对应 IO 设置为输出

11.2.3.2. CPU 屏 8080 总线初始化

CPU 屏的初始化可以参考“附录”的实例。
显示驱动提供 5 个接口函数可供使用。如下:

函数:LCD_CPU_WR
功能:设定 CPU 屏的指定寄存器为指定的值
原型:void LCD_CPU_WR(__u32 sel, __u32 index, __u32 data)
函数内容为

void LCD_CPU_WR(__u32 sel, __u32 index, __u32 data)
{
    LCD_CPU_WR_INDEX(sel, index);
    LCD_CPU_WR_DATA(sel, data);
}

实现了 8080 总线上的两个写操作。
LCD_CPU_WR_INDEX 实现第一个写操作,这时 PIN 脚 RS(A1)为低电平,总线数据上的数据内容为参数index 的值。
LCD_CPU_WR_DATA 实现第二个写操作,这时 PIN 脚 RS(A1)为高电平,总线数据上的数据内容为参数data 的值。

函数:LCD_CPU_WR_INDEX
功能:设定 CPU 屏为指定寄存器
原型:void LCD_CPU_WR(__u32 sel, __u32 index, __u32 data)
void LCD_CPU_WR_INDEX(__u32 sel,__u32 index);
具体说明见 LCD_CPU_WR。

函数:LCD_CPU_WR_DATA
功能:设定 CPU 屏寄存器的值为指定的值
原型:void LCD_CPU_WR_DATA(__u32 sel, __u32 data);
具体说明见 LCD_CPU_WR。

函数:LCD_CPU_AUTO_FLUSH
功能:开启 CPU 屏的刷新
原型:void LCD_CPU_AUTO_FLUSH(__u32 sel, __bool en);
参数说明:
en = 1:8080 总线上开始传送显示 BUFFER 的数据,实现 CPU 屏的刷新

函数:LCD_cpu_register_irq
功能:设置 LCD_GPIO PIN 脚为输入或输出模式
原型:void LCD_CPU_register_irq(__u32 sel, void (*Lcd_cpuisr_proc) (void))
注册 cpu 屏的中断处理函数,驱动会在每个 vblanking 中断里调用一下用户注册的中断处理函数
Lcd_cpuisr_proc。
CPU 屏的初始化对应于开屏步骤函数的 LCD_panel_init。在 CPU 屏 LCD_panel_init 函数的最后,需要进行两个操作步骤:
1、使用 LCD_CPU_register_irq 注册 CPU 屏的中断处理函数 Lcd_cpuisr_proc,该函数的内容,可以是CPU 屏 GRAM 的 X 和 Y 坐标设置为零的操作,以保证异步屏每帧进行一次同步。
2、调用 LCD_CPU_AUTO_FLUSH(sel,1)打开显示数据传送。
示例如下:

static void LCD_panel_init(__u32 sel)
{
    kgm281i0_init(sel); //initial lcd panel
    kgm281i0_write_gram_origin(sel); //set gram origin
    LCD_CPU_register_irq(sel,Lcd_cpuisr_proc); //resgister cpu irq func
    LCD_CPU_AUTO_FLUSH(sel,1); //start sent gram data

}

区别于模拟串行接口的初始化,LCD_open_flow 中,CPU 屏的初始化 LCD_panel_init 放在 TCON_open之后,示例如下:

static __s32 LCD_open_flow(__u32 sel)
{
    LCD_OPEN_FUNC(sel, LCD_power_on,10);
    LCD_OPEN_FUNC(sel, TCON_open, 100);
    LCD_OPEN_FUNC(sel, LCD_panel_init, 50);
    LCD_OPEN_FUNC(sel, LCD_bl_open, 0);
    return 0;
}

11.2.4. 其它函数

11.2.4.1. GPIO 操作函数

用户有可能有需要自己对某些 GPIO 进行操作,显示驱动封装了几个函数提供给用户,它们屏避了操作系统间的差异,也就是说在不同的操作系统中都可以使用。

函数:OSAL_GPIO_Request
功能:申请 GPIO;
原型:__hdle OSAL_GPIO_Request(user_gpio_set_t *gpio_list, __u32 group_count_max);
参数说明:
gpio_list 为 GPIO 的设置,该结构体如下:

typedef struct
{
	char gpio_name[32];
	int port;
	int port_num;
	int mul_sel;
	int pull;
	int drv_level;
	int data;
}	user_gpio_set_t;

group_count_max: 要设置 GPIO 的个数. 函数返回: 成功返回 GIPO 的句柄, 失败返回 0.

函数:OSAL_GPIO_Release
功能:释放 GPIO. 原型:__s32 OSAL_GPIO_Release(__hdle p_handler, __s32 if_release_to_default_status);
参数说明:
p_handler: GPIO 的句柄.
if_release_to_default_status: 0/1: 表示释放后的GPIO处于输入状态;2: 表示释放后的 GPIO状态不变. 函数返回:成功返回 0, 失败返回错误号
将 GIPO PH6 输出高电平,示例如下:

static void LCD_vcc_on(__u32 sel)
{
    user_gpio_set_t gpio_list;
    int hdl;
    gpio_list.port = 8;// 1:A; 2:B; 3:C; 4:D;5:E;6:F;7:G;8:H.....
    gpio_list.port_num = 6;
    gpio_list.mul_sel = 1;
    gpio_list.pull = 0;
    gpio_list.drv_level = 0;
    gpio_list.data = 1;
    hdl = OSAL_GPIO_Request(&gpio_list, 1);
    OSAL_GPIO_Release(hdl, 2);
};

11.2.4.2. 延时函数

驱动提供了毫秒和微秒级的延时给用户使用, 不过建议如果延时时间比较长的话可以在开关屏流程里
新添新的函数. 因为在 boot 系统里延时是死等的,效率会比较低;如果放在开关屏流程里的话会启用 timmer去做延时,在延时期间 CPU 可以做其它的工作.

函数:LCD_delay_ms
功能:延时 ms 毫秒
原型:void LCD_delay_ms(__u32 ms)

函数:LCD_delay_us
功能:延时 us 微秒
原型:void LCD_delay_us(__u32 us)

11.3. TCON 参数说明

11.3.1. 接口参数说明

11.3.1.1. lcd_if

设置相应值的对应含义为:
0:HV(RGB 同步屏)接口
1:CPU(8080)接口
2:TTL
3:LVDS 接口

11.3.1.2. lcd_hv_if

Lcd HV panel Interface
这个参数只有在 lcd_if=0 时才有效。定义 RGB 同步屏下的几种接口类型。
设置相应值的对应含义为:
0:Parallel RGB
1:Serial RGB/ Serial YUV
该参数结合 3.1.3 的 lcd_hv_smode 定义了屏的接口类型。

11.3.1.3. lcd_hv_smode

Lcd HV panel Serial Mode
这个参数只有在 lcd_if=0 且 lcd_hv_if=1 时才有效。定义 RGB 同步串行接口屏的类型。
设置相应值的对应含义为:
0:Serial RGB
1:Serial YUV(CCIR656)
RGB 同步屏的接口类型可参考“附录 5.1.1 HV RGB 同步屏接口”。

11.3.1.4. lcd_hv_s888_if

Lcd HV panel Serial RGB output Interface
这个参数只有在 lcd_if=0 且 lcd_hv_if=1 且 lcd_hv_smode=0(Serial RGB)时才有效。
(lcd_hv_s888_if & 0xC)>>2 得到的值,定义了奇数行 RGB 输出的顺序
0: R→G→B
1: B→R→G
2: G→B→R
(lcd_hv_s888_if & 0x3)得到的值,定义了偶数行 RGB 输出的顺序
0: R→G→B
1: B→R→G
2: G→B→R

11.3.1.5. lcd_hv_syuv_if

Lcd HV panel Serial YUV output Interface

这个参数只有在 lcd_if=0 且 lcd_hv_if=2 且 lcd_hv_smode=1(Serial YUV)时才有效。

(lcd_hv_syuv_if & 0xC)>>2 得到的值,定义了 YUV 输出格式
0:YUYV
1:YVYU
2:UYVY
3:VYUY
(lcd_hv_syuv_if & 0x3) 得到的值,定义 CCIR656 编码时 F 相对有效行延迟的行数

0:F toggle right after active video line
1:Delay 2 lines (CCIR NTSC)
2:Delay 3 lines (CCIR PAL)

11.3.1.6. lcd_cpu_if

Lcd CPU panel Interface
这个参数只有在 lcd_if=1 时才有效。
设置相应值的对应含义为:
0:18bit×1cycle parallel (RGB666)
4:16bit×1cycle parallel (RGB565)
5:9bit×2cycle serial (RGB666)
7:8bit×2cycle serial (RGB565)
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第72张图片

11.3.1.7. lcd_lvds_bitwidth

Lcd LVDS panel Bit Width
设置相应值对应含义为:
0:24bit
1:18bit
相关说明可参见“附录 5.1.3 LVDS 屏接口”

11.3.1.8. lcd_lvds_mode

Lcd LVDS Mode
这个参数只有在 lcd_lvds_bitwidth=0 时才有效
设置相应值对应含义为:
0:NS mode
1:JEIDA mode
NS mode 和 JEIDA mode 的说明可参见“附录 5.1.3 LVDS 屏接口”。

11.3.2. 时序参数说明

11.3.2.1. lcd_x

显示屏宽的像素个数

11.3.2.2. lcd_y

显示屏高的像素个数

11.3.2.3. lcd_ht

Horizontal Total time
指一行总的 dclk 的 cycle 个数。见图 3-1。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第73张图片

11.3.2.4. lcd_hbp

Horizontal Back Porch
指有效行间,行同步信号(hsync)开始,到有效数据开始之间的 dclk 的 cycle 个数。见图 3-1。

11.3.2.5. lcd_vt

Vertical Total time
指两场的总行数。见图 3-2。
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第74张图片

11.3.2.6. lcd_vbp

Vertical Back Porch
指场同步信号(vsync)开始,到有效数据行开始之间的行数。见图 3-2。

11.3.2.7. lcd_hv_hspw

Horizontal Sync Pulse Width
指行同步信号的宽度。单位为 1 个 dclk 的时间(即是 1 个 data cycle 的时间)。
见图 3-1。

11.3.2.8. lcd_hv_vspw

Vertical Sync Pulse Width
指场同步信号的宽度。单位为行。见图 3-2

11.3.2.9. lcd_dclk_freq

Data Clock Frequency
指 PIN 总线上数据的传送频率。单位为 MHz。
屏幕刷新帧数 = (dclk_freq) / (ht×vt/2)

11.3.2.10. lcd_io_cfg0

Lcd IO Configuration0
这个参数提供 RGB 同步屏的相位调节。
lcd_dclk_freq < 40 时,该参数可设置为 0x00000000,0x04000000,0x10000000,0x14000000,
0x20000000,0x24000000,对应 LCD DCLK 的六个不同相位。
lcd_dclk_freq > 40 时,该参数可设置为 0x00000000,0x04000000 对应 LCD DCLK 的两个不同相位。
补充说明 1:hbp 在部分屏规格书的定义里并不包括 hspw。这种情况下,要正确配置 AW 的 TCON,
hbp(aw)=hbp(panel)+hspw(panel)。vbp 的定义同 hbp。
补充说明 2:F20 的 TCON 中,图 3-1 中的 hfp,图 3-2 中的 vfp 不能为 0。

11.3.3. 其他参数说明

11.3.3.1. lcd_pwm_freq

Lcd backlight PWM Frequency
这个参数配置 lcd_pwm 信号的频率,单位为 KHz。 F20 中可以输出的 PWM 频率为 1KHz-100KHz。

11.3.3.2. lcd_gamma_correction_en

Lcd Gamma Correction Enable
设置相应值的对应含义为:
0:TCON 的 Gamma 校正关闭
1:TCON 的 Gamma 校正打开
设置为 1 时,需要对 lcd_gamma_tbl [256]进行赋值。

11.3.3.3. lcd_gamma_tbl

Lcd Gamma Table
该参数为一个数组__u32 lcd_gamma_tbl[256];
lcd_gamma_tbl[n] = rout<<16 | gout<<8 | bout<<0 表示:输入 r=n 时,输出 r=rout;输入 g=n 时,
输出 g=gout;输入 b=n 时,输出 b=bout。
用户使用 Gamma 校正功能时,可以使用函数 lcd_gamma_gen(__panel_para_t * info)对其赋值,函数
内容可自由实现。具体可参考附录中的实例。

11.4. 屏文件实例

路径:\eMod\drv_display\lcd\lcd_bak

12. 应用程序开发

12.1. APP framework 体系结构

12.1.1. APP framework 简介

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第75张图片
每个应用程序(AppletPlugin)都是一个插件,实现 APPLET_PLUGIN_INTERFACE(应用程序插件接口),再将应用程序注册到系统中就可以被系统管理。新的方案中只有一个主应用 app_root,再由主应用启动子应用(home、music、movie)以实现多应用切换。主应用 app_root 已经由系统创建,并默认启动子应用 home。
Desktop 是新方案主框架,以动态库形式存在,提供包括应用插件管理、消息循环、系统事件处理、系统服务等功能接口。用户应用可以调用 Desktop 提供的功能接口以使用系统功能。框架实现由 init 模块完成,Desktop 不进行实际操作。
Init 模块调用 Desktop 提供的接口实现应用插件管理、消息循环、系统事件处理,另外提供输出切换,关屏设置的内部实现、背景管理、headbar 管理、系统对话框管理等接口供用户应用使用。
Orange 是 GUI 主体,提供完整的 GUI 绘制方法、图层管理、消息处理和基本控件管理,并封装一系列API 供用户使用。用户应用可以调用 GUI 绘制方法,添加控件以显示图形界面,再处理 GUI 消息实现交互。
Melis 还提供其他库文件,如 elibs_ex.a 图片功能库 anole、视频音频功能库 robin、文件搜索和播放
列表库 rat 等,app_views.a 列表库供应用程序使用。

12.2. DESKTOP

12.2.1. desktop 简介

桌面系统的层次结构如下图:

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第76张图片
内核启动后,Shell 开始运行。Shell 执行 startup.esh 脚本,开始初始化 GUI 和 Desktop。Desktop
负责初始化系统资源,包括文字、图片、声音、字体、字库资源,headbar、background、dialog 组件等,为应用提供 API 以使用系统功能。初始化消息循环服务,最后启动应用。
Desktop 系统服务由 init 主管理窗口完成,在窗口回调函数 init_mainwin_cb()中完成具体服务。回
调中集中处理了系统消息,用户可以在此回调中处理更多消息。

消息 ID                             消息描述
-----------------------------------------------------------------------------
DSK_MSG_POWER_OFF                   关机

DSK_MSG_LOW_POWER                   低电

DSK_MSG_USBD_PLUG_IN usb device     插入

DSK_MSG_USBD_PLUG_OUT usb device    拔出

DSK_MSG_SCREEN_OPEN                 开屏

DSK_MSG_SET_SCN_CLOSE               关屏

DSK_MSG_FS_PART_PLUGIN              添加分区,表明 sd 卡插入或 host 加载

DSK_MSG_FS_PART_PLUGOUT             删除分区,表明 sd 卡拔出或 host 卸载

DSK_MSG_HDMI_PLUGIN hdmi            插入

DSK_MSG_HDMI_PLUGOUT hdmi           拔出

DSK_MSG_TVDAC_PLUGIN tvdac          插入

DSK_MSG_TVDAC_PLUGOUT tvdac         拔出

DSK_MSG_STANDBY                     系统进入 standby

DSK_MSG_STANDBY_WAKE_UP             系统从 standby 恢复

DSK_MSG_FW_UPDATE                   固件升级
-----------------------------------------------------------------------------

Desktop 模块中系统控制接口包含在 functions 文件夹下,是应用程序经常使用的功能集合。主要包含
如下部分:

 显示驱动相关接口:dsk_display.h;

 固件升级接口:dsk_fw_update.h;

 按键音接口:dsk_keytone.h;

 音量接口:dsk_voice.h;

 音频输出设备接口:dsk_audio_if.h;

 媒体库接口:dsk_orchid.h;

 电源管理相关接口:dsk_power.h;

 usb device 相关接口:dsk_usbd.h;

 usb host 相关接口: dsk_usbh.h;

 字符集设置接口:dsk_charset.h;

 语言资源操作接口:dsk_langres.h;

 图片资源操作接口:dsk_theme.h;
Desktop 消息服务在 init 服务线程 application_init_process()中完成,主要采集按键和触摸消息,
并将消息发送到 GUI。按键和触摸消息首先会发送到输入子系统,由输入子系统对消息进行封装,再发送到GUI。用户不需要关心消息服务具体实现,在应用程序中响应系统消息即可。消息机制介绍详见第 4 章。

12.3. GUI 窗口体系和消息机制

Melis 应用程序由窗口组成,所有用户的操作(触摸、按键)都通过消息发送到窗口,在窗口的消息处
理函数中进行处理。窗口体系和消息传递都在 GUI 实现。

12.3.1. 窗口类型

 Manage window(管理窗口)
虚拟窗口,负责消息分发和处理,作为应用程序的入口主窗口,有自己的消息队列。

 Layer window(图层窗口)
图层窗口对应的一个图层,是屏幕管理的基本单位,屏幕中的一个实体窗口,有自己的显示区域和 Z
序,也是 frame window 和控件窗口的载体。

 Frame window
寄生在 framebuffer 上,实体窗口,有自己的矩形区域,可以再上面写字,画图。

 Ctrl window(控件窗口)
封装好的具有特定属性和操作的特殊窗口,如 button、slider 等。

12.3.2. 消息机制

 外部事件消息
主要指由外设触发而由输入子系统传递给 GUI 消息接收器的消息,如触摸、按键消息。

 GUI 系统消息
主要指由外部事件或相应的函数触发的消息,如绘制、大小改变、设焦等相关的消息。

 消息优先级
根据消息的优先级的不同又分为同步消息,异步消息(通知消息)。对同步消息而言,发送线程需要
等消息执行完成之后再返回,同步消息往往用来处理高优先级的消息。异步消息往往用于非高优先级的消息,对异步消息而言,发送线程只需要将消息投递到指定的消息队列中之后然后返回,并不等消息完全执行完毕。
需 要 注 意 的 是 , 区 分 同 步 消 息 和 异 步 消 息 并 不 在 消 息 本 身 , 而 在 选 择 发 送 消 息 的 方 式 ,GUI_SendMessage()发送同步消息,GUI_SendNotifyMessage()发送异步消息。

 消息路由
创建 Manage window 和 Frame window 时需要指定他们的窗口回调函数,即消息处理函数,所有消息的响应均在这个回调函数里实现。
通过 GUI_SetActiveManWin()可以指定哪个 Root 下面第一级管理窗口为 Active window,触摸消息会
根据触摸区域选定焦点 Frame window,触摸消息通过 Active window 直接传递给焦点 Frame window;通过GUI_WinSetFocusChild 可以指定按键消息焦点窗口(Manage window 或 Frame window),按键消息会从 Activewindow 逐级传递到焦点窗口。

12.4. 资源使用

12.4.1. 应用字符串资源

字符串资源是打包生成的 lang.bin 文件,包含应用中使用到的所有特定字符串,例如主界面上应用名称
“音乐”、“电影”等文字,不包括电影字幕,歌曲歌词。系统调用 bin 文件目的是方便管理和多国语言切
换。通过资源 ID 调用对应字符串,调用 Destop 提供的 dsk_langres_set_type()即可切换多国语言。

12.4.1.1. 制作字符串资源

在路径 ROOT\livedesk\beetles\res 中 lang 文件夹存放字符串资源。文件夹中分别存放各个应用使用的字符串资源。下面以 home 主界面为例,介绍字符串资源制作方法。

1、准备字符串资源:在 ROOT\livedesk\beetles\res\lang\下面新建文件夹 home,在 home 下面新建一个excel 命名为 home.xls,将要添加的字符串按照下面的格式填写到 excel 文件中,包括 ID、中文、繁体中文、英文。将表格另存为 Unicode 文本(home.txt)保存在 home 文件夹下。如果要使用更多语言,则多添加对应列数字符串集,并修改 lang.xml 文件。
2、修 改lang.xml :
全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第77张图片
打 开ROOT\livedesk\beetles\res\lang\lang.xml。
修改并在其后一个行添加

<OSDItem name="home" startid="1001" maxid="2000" file="home\home.txt"/>

其中表示应用个数为 3,startid 和 maxid 表示生成资源 ID 可用范围。
其中表示有 3 种语言。

<OSDTable>
<Groups count="3">
<OSDItem name="home" startid="1001" maxid="2000" file="home\home.txt"/>
<OSDItem name="movie" startid="3001" maxid="4000" file="movie\movie.txt"/>
<OSDItem name="music" startid="4001" maxid="5000" file="music\music.txt"/>
</Groups>
<LangType count="3">
<LangItem name="ChineseS" langId="0x410"/>
<LangItem name="ChineseT" langId="0x420"/>
<LangItem name="English" langId="0x400"/>
</LangType>
<Output bin=".\lang.bin" head=".\lang.h"/>
</OSDTable>

3、生成 lang.bin:打开 Cygwin,cd 到 ROOT\livedesk\beetles\res\lang,输入命令 make,回车,即可将准备好的字符串资源打包进 lang.bin,并拷贝到ROOT\workspace\suniv\beetles\rootfs\apps\lang.bin,相应的字符串资源 ID 见 ROOT\livedesk\beetles\include\res\lang.h。

12.4.1.2. 使用字符串资源

字符串资源的使用参见下面的伪代码:
字体和编码一般在应用初始化和退出时操作,在应用中获取和显示字符串即可。

char text[128];
GUI_RECT txtrect;
GUI_FONT *SWFONT;
//创建字体

SWFONT = GUI_SFT_CreateFont(24, "d:\\res\\fonts\\font24.sft");
//设置字符串显示区域

txtrect.x0 = 0;
txtrect.y0 = 0;
txtrect.x1 = 50;
txtrect.y1 = 24;
//通过 ID:STRING_EXPLORE 获取字符串内容,存入 text
dsk_langres_get_menu_text(STRING_EXPLORE, text, 128);
//选择显示的图层,图层 layer 的创建参考 5.1 节

GUI_LyrWinSel(layer);
//设置显示编码(MELIS 上总是 UTF8)

GUI_UC_SetEncodeUTF8();
//选择字体

GUI_SetFont(SWFONT);
//显示字符串,水平居中

GUI_DispStringInRect(text, &txtrect, GUI_TA_HCENTER|GUI_TA_VCENTER);
//释放字体

GUI_SetFont(GUI_GetDefaultFont());
GUI_SFT_ReleaseFont(SWFONT);

12.4.2. 应用图片资源

12.4.2.1. 制作应用图片资源

应用图片资源指的是应用中用到的特定图片,例如主界面的应用图标、headbar 充电图标等,不包括歌曲专辑图等。通过图片 ID 即可访问图片资源。下面以 home 主界面为例,介绍图片资源制作方法。
1、准备图片:在 ROOT\livedesk\beetles\res\theme\下面新建文件夹 home,拷贝所有图片到 home 文件夹中。图片资源只能使用 bmp 图片,其他图片文件格式请使用图片转换工具进行转换。系统提供了 png批量转 bmp 工具:eStudio\Softwares\PngTrans\ PngTrans.exe。转换完成后可根据需要压缩 bmp 图片,系统提供了 bmp 压缩工具\tool\bmp_pack_compress.bat
2、修改 makefile:编辑 ROOT\livedesk\beetles\res\theme\makefile。在# make scripts for every
application 和# create theme for the whole case 和# 删除生成的中间文件 三个位置中添加 home 应用信息,其中# make scripts for every application

# make scripts for every application
    $(SDKROOT)/tools/build_tools/Face200/MakeScript/MakeScript.exe ./home 1001 2000
    $(SDKROOT)/tools/build_tools/Face200/MakeScript/MakeScript.exe ./movie 2001 3000
    $(SDKROOT)/tools/build_tools/Face200/MakeScript/MakeScript.exe ./music 4001 5000
# create theme for the whole case
    -rm touchtheme.script cat ./config/touchthemehdr.script \
        ./home/home.script \
        ./movie/movie.script \
        ./music/music.script \ >> touchtheme.script
# 删除生成的中间文件

clean:
    -rm ./theme.bin
    -rm ./touchtheme.face
    -rm ./theme.h
    -rm ./touchtheme.script
    -rm ./home/home.script

3、生成 theme.bin。打开 Cygwin,cd 到 ROOT\livedesk\demo\res\theme,输入命令 make,回车,即可将准备好的图片资源打包进 theme.bin,并拷贝到ROOT\workspace\suniv\beetles\rootfs\apps\theme.bin,相应的图片资源 ID 见
ROOT\livedesk\beetles\include\res\theme.h。

12.4.2.2. 使用应用图片资源

应用图片资源的使用参见下面的伪代码:

HTHEME h_bmp;
void * bmp_buf;
//打开图片资源,获取资源句柄

h_bmp = dsk_theme_open(ID_DESKTOP_CURSOR_8BPP_BMP);
//通过资源句柄获取资源 buffer
bmp_buf = dsk_theme_hdl2buf(h_bmp);
//选择贴图的图层

GUI_LyrWinSel(layer);
//绘制贴图

GUI_BMP_Draw(bmp_buf, 0, 0);
//不需要使用资源时,关闭资源句柄,释放资源(通常是在应用程序退出时)

dsk_theme_close(h_bmp);

12.4.3. 背景图资源

背景图单独存放于 ROOT\workspace\suniv\beetles\rootfs\apps,命名为 bg_default0.bgd。支持多
张背景图并切换。多张背景图命名形如 bg_default1.bgd、bg_default2.bgd,以此类推。
背景图制作方法:
1、背景图仅支持 bmp 格式,如果是其他格式,请先使用图片转换工具转换为 bmp。
2、使用工具 eStudio\Softwares\Convert2YUV\ConvertYUV.exe 将 bmp 转换为.bin 文件,
3、重新将文件命名为.bmp 后缀,使用 bmp 压缩工具将文件压缩。
4、将压缩图片重命名为 bg_default0.bgd,背景制作完成。
5、最后拷贝 bg_default0.bgd 文件至 ROOT\workspace\suniv\beetles\rootfs\apps 即可。

12.4.4. 启动图资源

启动图片存放于 ROOT\workspace\suniv\beetles\rootfs\res\boot_ui,命名为 logo.bmp,在系统启动期间
显示,应用启动前关闭启动图片显示。
启动图片仅支持 bmp 格式,使用 bmp 压缩工具压缩后存放至指定路径即可。
使用:在系统配置 sys_config.fex 文件中(路径:ROOT\workspace\suniv\eFex)找到配置:

[kernel_logo_para] ;启动图片配置

logo_enable = 1 ;1:启用启动图片 0:关闭启动图片

12.4.5. 按键音资源

按键音资源存放于 ROOT\workspace\suniv\beetles\rootfs\res\sounds,命名为 chord.wav,在按下
按键或触摸按下时播放对应音效。
使用:Desktop 已经提供按键音操作接口,详见 dsk_keytone.c。系统启动时已经初始化按键音,应用
中可直接使用接口播放按键音。

dsk_keytone_on()//播放一次按键音

12.4.6. 系统功能资源

12.4.6.1. headbar 标题栏

headbar 标题栏用于显示应用程序信息,如应用名称,显示系统信息如音量、时间、电量、屏幕亮度等,还可以显示用户自定义信息。除了显示信息功能外,headbar 也可以响应触摸或按键消息,这需要在 headbar的回调函数 cb_shbar_mwin()和 cb_headbar_framewin()中加入触摸或按键消息处理部分。用户也可以修改headbar 布局,实现自定义 headbar 显示。
headbar 默认显示信息有标题、亮度、音量、电量。桌面创建时已经初始化 headbar 相关资源,应用程序可以直接使用 Desktop 提供的 headbar 操作接口进行操作:
全局场景 headbar 的相关接口声明在 gscene_headbar.h 中:

typedef enum _HBarState
{
 HBAR_ST_SHOW, HBAR_ST_HIDE
}HBarState;
typedef enum tag_HBAR_FORMAT
{
 HBAR_FOARMAT_8BPP, HBAR_FOARMAT_32BPP
}__hbar_format_t;
typedef struct
{
 char *name; // 场景名称

__u16 sid; // 场景 id
H_WIN parent; // 父窗口

H_WIN layer; // 图层

GUI_FONT *font; // 字体句柄

}HBarCreatePara;
//创建 headbar(Init 模块调用)

__s32 gscene_hbar_create(HBarCreatePara *para);
//设置 headbar 状态

__s32 gscene_hbar_set_state(HBarState state);
//获取 headbar 状态

__s32 gscene_hbar_get_state(HBarState *p_state);
//title 为 utf8 编码格式字符串,len<=32 ,设置 headbar title 区域字符串

__s32 gscene_hbar_set_title(char *title, __u32 len);
//设置 headbar 音量条

__s32 gscene_hbar_set_volume(void);
//删除 headbar(Init 模块调用)

__s32 gscene_hbar_delete(void);

12.4.6.2. background 背景

全局场景 background 的相关接口声明在 gscene_backgrd.h 中:

typedef enum
{
 BGD_STATUS_SHOW, BGD_STATUS_HIDE
}bgd_status_t;
//背景图层初始化(init 模块调用)

__s32 gscene_bgd_init(SIZE *p_size, bgd_status_t status, __fb_type_t ftype);
//设置背景状态

void gscene_bgd_set_state(bgd_status_t status);
//查询背景状态

bgd_status_t gscene_bgd_get_state(void);
//背景图层优先级置顶

void gscene_bgd_set_top(void);
//背景图层优先级置底

void gscene_bgd_set_bottom(void);
//保存背景图片

void gscene_bgd_save_fb(FB *fb);
//设置背景图层格式

void gscene_bgd_set_fb_type(__fb_type_t ftype);
//刷新背景图层,从新绘制背景图片

void gscene_bgd_refresh(void);
//恢复默认背景图

void gscene_bgd_restore(void);
//背景图层反初始化(init 模块调用)

__s32 gscene_bgd_deinit(void);

12.5. 应用程序编写

12.5.1. 简单应用编写

用户程序编写最基本的 6 个步骤:注册应用、创建管理窗口 manwin 并实现回调函数、创建图层、创建framewin 并实现回调函数。下面进行介绍。

12.5.1.1. 注册应用

新方案中,只有一个主应用,子应用由主应用启动,用户应用程序为子程序。主应用默认启动 home
子应用,并由 home 子应用启动其他子应用。因此 home 子应用定义了要切换的子应用 ID。
ROOT\livedesk\beetles\applets\lib\beetles_app.h 文件中定义了子应用 ID 枚举 root_home_id_t,添加项ID_HOME_TEST_APP。

typedef enum
{
     ID_HOME_FM = 0, 
     ID_MEDIA_START, 
     ID_HOME_RECORD=ID_MEDIA_START, 
     ID_HOME_MOVIE, 
     ID_MEDIA_END, 
     ID_HOME_SETTING = ID_MEDIA_END, 
     ID_HOME_TEST_APP, 
     ID_MAX_NUM, 
 }  root_home_id_t;

为方便窗口、图层创建,在 ROOT\livedesk\beetles\applets\lib\beetles_app.h 加入定义,窗口或图层创建时使用此名称以进行区分。

#define APP_TEST "app_test"

12.5.1.2. 创建管理窗口

管理窗口是所有应用的入口,负责接收消息。创建管理窗口时,id 参数请使用注册 ID 即 APP_TEST。用户也可以添加自定义结构体用于参数传递,即 create_info.attr 参数。

_s32 app_test_create(root_para_t *para)
{ 
    __gui_manwincreate_para_t create_info;
    test_app_ctrl_t *test_app_ctrl = NULL; 
    __log("****************************************************************************************\n"); 
    __log("********************************** enter test app ************************************\n"); 
    __log("****************************************************************************************\n");
    test_app_ctrl = (test_app_ctrl_t)esMEMS_Balloc(sizeof(test_app_ctrl_t));
    
    if( test_app_ctrl == NULL )
    { 
        __msg("test app esMEMS_Balloc fail\n"); return NULL;
    }
    eLIBs_memset(test_app_ctrl, 0, sizeof(test_app_ctrl_t));
    test_app_ctrl->test_app_font = para->font;
    test_app_ctrl->root_type = para->root_type; 
    eLIBs_memset(&create_info, 0, sizeof(__gui_manwincreate_para_t)); 
    create_info.name = APP_TEST; 
    create_info.hParent = para->h_parent; 
    create_info.ManWindowProc = (__pGUI_WIN_CB)esKRNL_GetCallBack((__pCBK_t)_app_test_proc); 
    create_info.attr = (void*)test_app_ctrl; 
    create_info.id = APP_TEST; 
    create_info.hHosting = NULL; 
    return(GUI_ManWinCreate(&create_info));
}    

12.5.1.3. 实现管理窗口消息处理回调函数

消息处理函数为管理窗口中设置的回调函数,在发生消息传递时先被调用。主要集中处理
GUI_MSG_CREATE、GUI_MSG_DESTROY、GUI_MSG_CLOSE、GUI_MSG_KEY、GUI_MSG_TOUCH 等系统消息,也可以
处理用户自定义消息。

static __s32 _app_test_proc(__gui_msg_t *msg)
{ 
    __s32 ret; 
    switch( msg->id )
    {
        case GUI_MSG_CREATE: /* 创建子窗口*/
            layer = htouch_layer_create(); /* 创建图层*/
            GUI_LyrWinSetTop(layer); /* 图层置顶*/
            htouch_frmwin_create(msg->h_deswin, layer); /* 创建 framewin*/
            return EPDK_OK;
        /*释放在 create 中分配的资源,尽量在此回调中释放资源,而不要在退出消息循环后在释放资源*/ 
        case GUI_MSG_DESTROY: 
            GUI_LyrWinDelete(layer); 
            return EPDK_OK;
        /* 需要支持的桌面消息*/ 
        case DSK_MSG_HOME: /* 回到主界面 */ 
        case DSK_MSG_KILL: /* 强制杀掉该应用程序 */
            ret = GUI_ManWinDelete(msg->h_deswin); 
            return ret; 
        case GUI_MSG_CLOSE:
            GUI_ManWinDelete(msg->h_deswin);
            dsk_load_app("main.app"); /* 回到主界面 */
            return EPDK_OK; case GUI_MSG_KEY: /* 按键响应 */
            if( msg->dwAddData1 == GUI_MSG_KEY_ESCAPE )
            {
                GUI_ManWinDelete(msg->h_deswin);
                dsk_load_app("main.app"); return EPDK_OK;
            }
            break;
        default: break;
    }
    return GUI_ManWinDefaultProc(msg);/*默认处理流程*/
}        

12.5.1.4. 创建图层

此图层为应用程序显示区域,设置显示矩形区域位置和大小,设置区域格式为 ARGB 或者其他。图层成功创建完毕后将会返回图层句柄。

static H_LYR test_app_32bpp_layer_create(RECT *LayerRect)
{
    H_LYR layer = NULL;
    RECT LayerRect;
    FB fb =
    {
        {0, 0}, /* size */
        {0, 0, 0}, /* buffer */
        {FB_TYPE_RGB, {PIXEL_COLOR_ARGB8888, 0, (__rgb_seq_t)0}}, /* fmt */
    };
    
    __disp_layer_para_t lstlyr =
    {
        DISP_LAYER_WORK_MODE_NORMAL, /* mode */
        0, /* ck_mode */
        0, /* alpha_en */
        0, /* alpha_val */
        1, /* pipe */
        0xff, /* prio */
        {0, 0, 0, 0}, /* screen */
        {0, 0, 0, 0}, /* source */
        DISP_LAYER_OUTPUT_CHN_DE_CH1, /* channel */
        NULL /* fb */
    };

    __layerwincreate_para_t lyrcreate_info =
    { 
        "APP_TEST", 
        NULL, 
        GUI_LYRWIN_STA_SUSPEND, 
        GUI_LYRWIN_NORMAL
    };
    

    fb.size.width = LayerRect->width;
    fb.size.height = LayerRect->height;
    fb.fmt.fmt.rgb.pixelfmt = PIXEL_COLOR_ARGB8888;
    lstlyr.src_win.x = LayerRect->x;
    lstlyr.src_win.y = LayerRect->y;
    lstlyr.src_win.width = LayerRect->width;
    lstlyr.src_win.height = LayerRect->height;
    lstlyr.scn_win.x = LayerRect->x;
    lstlyr.scn_win.y = LayerRect->y;
    lstlyr.scn_win.width = LayerRect->width;
    lstlyr.scn_win.height = LayerRect->height;
    lstlyr.pipe = 1;
    lstlyr.fb = &fb;
    lyrcreate_info.lyrpara = &lstlyr;
    layer = GUI_LyrWinCreate(&lyrcreate_info);
    if( !layer )
    { 
        __err("test app layer create error !\n");
    }
    return layer;
}        

12.5.1.5. 创建 framewin

Framewin 需要传入创建的图层句柄,以操作图层。主要工作是绘图,如创建窗口绘图、按键或触摸改变焦点绘图等。这些工作在回调中实现。另外可以传入一些用户自定义结构体数据,即framewin_para.attr参数。

static H_WIN test_app_framewin_create(H_WIN h_parent, setting_general_para_t *para)
{ 
	__gui_framewincreate_para_t framewin_para;
	setting_general_para_t *general_para;
	FB fb;
	GUI_LyrWinGetFB(para->layer, &fb);
	eLIBs_memset(&framewin_para, 0, sizeof(__gui_framewincreate_para_t));
	framewin_para.name = "test_app win", framewin_para.dwExStyle = WS_EX_NONE;
	framewin_para.dwStyle = WS_NONE|WS_VISIBLE;
	framewin_para.spCaption = NULL;
	framewin_para.hOwner = NULL;
	framewin_para.id = GENERAL_MENU_ID;
	framewin_para.hHosting = h_parent;
	framewin_para.FrameWinPro= (__pGUI_WIN_CB)esKRNL_GetCallBack((__pCBK_t)htouch_frmwin_cb);
	framewin_para.rect.x = 0;
	framewin_para.rect.y = 0;
	framewin_para.rect.width = fb.size.width;
	framewin_para.rect.height = fb.size.height;
	framewin_para.BkColor.alpha = 0;
	framewin_para.BkColor.red = 0;
	framewin_para.BkColor.green = 0;
	framewin_para.BkColor.blue = 0;
	framewin_para.attr = NULL
	framewin_para.hLayer = para->layer;
	return (GUI_FrmWinCreate(&framewin_para));
}

12.5.1.6. 实现 framewin 消息处理回调函数

在此回调中完成图层绘制。可以在 GUI_MSG_CREATE 或 GUI_MSG_PAINT 消息中绘制应用界面,图片、文字的使用和绘制请参考第 5 章中。处理按键消息 GUI_MSG_KEY 或触摸消息 GUI_MSG_TOUCH,更新焦点等。应用程序能处理父窗口发送的 GUI_MSG_COMMAND 自定义命令,并完成相应的绘制或其他响应,此外也能发送响应结果到父窗口或其他目标窗口。

static __s32 htouch_frmwin_cb(__gui_msg_t *msg)
{ 
	switch( msg->id )
	{ 
		case GUI_MSG_CREATE: 
		{
	 		htoutch_frmw_ctr *ctr;
			button_para_t *para; ctr = esMEMS_Malloc(0, sizeof(htoutch_frmw_ctr));
			if( !ctr )
			{ 
				__err(" frmwin malloc fail \n"); return EPDK_FALSE;
			}
			eLIBs_memset(ctr, 0, sizeof(htoutch_frmw_ctr));
			para = &(ctr->para); 
			ctr->focus_size =get_res_them(&(para->focus_bmp), STYLEID,ID_HELLOTOUCH_FOCUS_PIC_BMP); 
			ctr->unfocus_size = get_res_them(&(para->unfocus_bmp), STYLEID,ID_HELLOTOUCH_UNFOCUS_PIC_BMP);
			para->bmp_pos.x = 0;
			para->bmp_pos.y = 0;
			htouch_static_ctl_create(msg->h_deswin, para);
			GUI_WinSetAddData( msg->h_deswin, (__u32)ctr); 
			return EPDK_OK;
		}
		case GUI_MSG_DESTROY: 
		{
	 		htoutch_frmw_ctr *ctr = (htoutch_frmw_ctr *)GUI_WinGetAddData(msg->h_deswin);
			free_res_them(ctr->para.focus_bmp, ctr->focus_size);
			free_res_them(ctr->para.unfocus_bmp, ctr->unfocus_size); 
			esMEMS_Mfree(0, ctr); 
			return EPDK_OK;
		}
		case GUI_MSG_CLOSE: 
		{
	 		GUI_FrmWinDelete(msg->h_deswin); 
	 		return EPDK_OK;
		}
		case GUI_MSG_COMMAND: 
		{ 
			switch(LOSWORD(msg->dwAddData1))
			{ 
				case ID_WIDGET_STATIC: 
				{ 
					switch( HISWORD(msg->dwAddData1) )
					{
						case BN_CLICKED: 
						{ 
							__gui_msg_t msgex; 
							eLIBs_memset(&msgex, 0, sizeof(__gui_msg_t)); 
							msgex.id = GUI_MSG_CLOSE; 
							msgex.h_srcwin = 0; 
							msgex.h_deswin = GUI_WinGetManWin(msg->h_deswin);
							GUI_SendNotifyMessage(&msgex);
							break;
						}
					}
					break;
				}
			}
			return EPDK_OK;
		}
		default: 
			break;
	}
	return GUI_FrmWinDefaultProc(msg);
}

13. 全志相关工具和资源

13.1 全志固件镜像修改工具 ImageModify.exe 下载

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第78张图片
下载地址:
固件镜像修改工具 ImageModify.exe下载 ImageModify_20230906.rar

13.2 全志固件USB刷机工具 PhoenixSuit 下载

全志F1C200S ARM926 Melis2.0系统的开发相关工具文档及SDK源码库_第79张图片
下载地址:
USB刷机工具 PhoenixSuit下载 PhoenixSuit_CN_V1.1.1_20230906.rar

13.3 全志Melis2.0 用户手册.pdf下载

下载地址:
全志Melis2.0 用户手册.pdf下载 documents_20230906_melis_v2.0.rar

13.4 全志melis2.0 sdk源码库下载

下载地址:
全志melis2.0 sdk源码库下载 melis2.0-sdk-release_20230906V2.0.rar

你可能感兴趣的:(ARM,MCU,Linux,CPLD,linux,服务器,运维,arm开发,c语言)