在Windows模拟器中使用LVGL8.3
引言
LVGL是一个跨平台、轻量级、易于移植的图形库。也因其支持大量特性和其易于裁剪,配置开关众多,且版本升级较快,不同版本之间存在一定的差异性,相关的使用教程有一定的滞后性,由于缺少最新版本的中文教程,加上大量的教程中未注明对应的版本,初始接触的开发者往往容易中招,花费大量时间爬坑,本文特对自己的使用经验进行记录和总结,以期对初始接触LVGL的开发者有所帮助。
简介
什么是Lvgl?LVGL(轻巧而多功能的图形库)是一个免费的开放源代码图形库,它提供创建具有易于使用的图形元素,精美的视觉效果和低内存占用的嵌入式GUI所需的一切。
主要特性
l 功能强大的构建块,例如按钮,图表,列表,滑块,图像等。
l 带有动画,抗锯齿,不透明,平滑滚动的高级图形
l 各种输入设备,例如触摸板,鼠标,键盘,编码器等
l 支持UTF-8编码的多语言
l 多显示器支持,如TFT,单色显示器
l 完全可定制的图形元素
l 独立于任何微控制器或显示器使用的硬件
l 可扩展以使用很少的内存(64 kB闪存,16 kB RAM)进行操作
l 操作系统,支持外部存储器和GPU,但不是必需的
l 单帧缓冲区操作,即使具有高级图形效果
l 用C语言编写,以实现最大的兼容性(与C ++兼容)
l 模拟器可在没有嵌入式硬件的PC上进行嵌入式GUI设计
l 可移植到MicroPython
l 可快速上手的教程、示例、主题
l 丰富的文档教程
l 在MIT许可下免费和开源
LVGL硬件要求
- 16、32或64位微控制器或处理器
- 最低 16 MHz 时钟频率
- Flash/ROM::对于非常重要的组件要求 >64 kB(建议 > 180 kB)
- RAM
- 静态 RAM 使用量:~2 kB,取决于所使用的功能和对象类型
- 堆栈: > 2kB(建议 > 8 kB)
- 动态数据(堆):> 2 KB(如果使用多个对象,则建议 > 16 kB)。由 lv_conf.h 中的 LV_MEM_SIZE 宏进行设置。
- 显示缓冲区:> “水平分辨率”像素(建议 > 10× “水平分辨率” )
- MCU 或外部显示控制器中的一帧缓冲区
- C99或更高版本的编译器
- 具备基本的C(或C ++)知识:指针,结构,回调...
请注意,内存使用情况可能会因具体的体系结构、编译器和构建选项而异。
官方网址
LVGL - Light and Versatile Embedded Graphics Library
源码地址 https://github.com/lvgl/lvgl
- lvgl官方文档网站(https://docs.lvgl.io)
- lvgl官方博客博客站点(https://blog.lvgl.io)
- sim在线模拟器网站(https://sim.lvgl.io)
部分中文资料网址
欢迎阅读百问网LVGL中文开发手册! — 百问网LVGL中文教程文档 文档 (100ask.net)
环境搭建
本文主要针对在windows10下,使用visual stdio开发环境编译运行模块器对LVGL8.3开发测试的一些配置使用进行介绍。
VS2019或VS022均可,Visual Stdio和Git工具的安装使用,在此不做介绍。
Visual Studio simulator模拟器为开源项目,源码地址如下:
https://github.com/lvgl/lv_port_win_visual_studio
模拟器源码项目下载
模拟器项目源码内部包含了引用特定版本代码库模块,通过文件下载方式下载,会存在引用模块为空的问题。
Github站点的英文说明文档中介绍了推荐的下载方式,采用git下载,但与我们通常下载单个源码库有所不同。
此存储库包含其他必要的 LVGL 软件存储库作为 git 子模块。这些子模块不会使用正常的 git clone 命令拉入,它们将被需要。有几种技术可以拉入子模块。
此命令将在单个步骤中克隆lv_sim_visual_studio存储库和所有子模块。
git clone --recurse-submodules https://github.com/lvgl/
lv_sim_visual_studio.git
众所周知,国内的网络环境,访问github比较抽风,这种方式,通常会失败。
因此,推荐使用下面的方式下载
git clone https://github.com/lvgl/lv_sim_visual_studio.git
cd lv_sim_visual_studio
git submodule update --init –recursive
先单独下载模拟器主项目,再切换到模拟器项目目录,使用模块拉取命令下载,这样,即使用失败了,可以通过反复尝试,可以将模块代码拉取回来。
模拟器使用
模块器项目代码成功拉取后,使用VS2019或VS2022成功打开即可运行。
模拟器项目中,lvgl的配置文件中,大部分可用宏已默认开启,这个与MCU项目下配置模板中的有所不同,毕竟电脑上模拟器可以有充足的硬件资源可供分配。
lv_conf.h 中的LV_MEM_SIZE宏应为 128KB 或更大,因为在使用 64 位模拟器时可能会遇到内存不足问题。 注意:在此项目中,大小设置为 1024KB。 用户需要检查在Visual Studio中选择的目标,因为模拟器项目支持ARM64,Visual Studio会因为字母顺序在第一时间选择ARM64。
自带例程使用
LVGL.Simulator.cpp文件中,main函数内,默认使用的lv_demo_widgets()演示例程,其后有各类其他演示例程,只需注释掉lv_demo_widgets()演示例程调用,分别启用其他例程即可。
文件系统使用
LVGL8.3版本的fsdrv目录中,已自带lv_fs_win32的文件系统调用接口,在模拟器中使用无需另外移植lv_fs_port文件,但需要在相关的配置文件中进行相关宏定义开启和相关配置。
Lv_conf.h配置文件中,文件系统宏默认已开启
#define LV_USE_FS_WIN32 '/'
//#define LV_FS_WIN32_PATH "C:\\Users\\john\\"
文件系统的访问路径配置为注释状态,可启用该宏定义并指向所需访问的磁盘文件目录,否则,文件系统默认访问项目的当前路径。
修改配置如下
#define LV_USE_FS_WIN32 '/'
#define LV_FS_WIN32_PATH "D:\\SD"//此处可使用你自己的目录
然后,开启main函数中的如下代码
//::lv_fs_win32_init();
lv_fs_dir_t d;
if (lv_fs_dir_open(&d, "/") == LV_FS_RES_OK)
{
char b[MAX_PATH];
memset(b, 0, MAX_PATH);
while (lv_fs_dir_read(&d, b) == LV_FS_RES_OK)
{
printf("%s\n", b);
}
lv_fs_dir_close(&d);
}
运行程序,查看控制台窗口,是不是应该出现指定目录下的所有目录和文件呢?
然而,并没有。
这一步也是LVGL默认模拟器项目比较坑的地方,没有默认给出需要的配置项,这一处也折腾我跟踪代码,分析了好久,说起来都是泪啊。
到底应该怎么办呢?
运行并跟踪代码,在lv_init()中会调用lv_fs_win32_init(),在这个函数中,对文件驱动器进行了初始化
static lv_fs_drv_t fs_drv; /*A driver descriptor*/
lv_fs_drv_init(&fs_drv);
/*Set up fields...*/
fs_drv.letter = LV_FS_WIN32_LETTER;
fs_drv.cache_size = LV_FS_WIN32_CACHE_SIZE;
定位查看LV_FS_WIN32_LETTER宏,发现在lv_conf_internal.h中,
如果外部未定义,会被定义为'\0',其后注释说明,需设置为设置驱动器可访问的大写字母。
如此处不进行定义,当lv_fs_dir_open函数中调用lv_fs_get_drv(letter)方法时,其内部的判断
(*drv)->letter == letter会无法匹配而导致无法返回可用的驱动器对象。
我们可以修改lv_conf_internal.h文件中(2035行)处的LV_FS_WIN32_LETTER宏定义,或者在lv_conf.h文件中,在宏 LV_USE_FS_WIN32 的下面,增加一行如下定义即可
#define LV_FS_WIN32_LETTER '/'
再次运行模拟器,bingo,指定目标下的目录和文件,在控制台中被打印输出出来了
使用矢量字体
模拟器项目中,默认已提供了矢量字体示例,打开注释开关启用,同时注释掉后面的演示Demo调用即可。
// ----------------------------------
// my freetype application
// ---------------------------------- ///*Init freetype library // *Cache max 64 faces and 1 size*/
lv_freetype_init(64, 1, 0);
///*Create a font*/
static lv_ft_info_t info;
info.name = "./lvgl/src/extra/libs/freetype/arial.ttf";
info.weight = 36;
info.style = FT_FONT_STYLE_NORMAL;
lv_ft_font_init(&info); /*Create style with the new font*/
static lv_style_t style;
lv_style_init(&style);
lv_style_set_text_font(&style, info.font);
/*Create a label with the new style*/ lv_obj_t* label = lv_label_create(lv_scr_act());
lv_obj_add_style(label, &style, 0);
lv_label_set_text(label, "FreeType Arial Test");
默认矢量字体例程是英文字体,我们要使用中文矢量字体怎么处理呢?
在我们之前建立的文件系统目录中,放置对应的中文字体
//info.name = "./lvgl/src/extra/libs/freetype/arial.ttf";
info.name = "D:/SD/TTF/simhei.ttf";
此处须使用完整路径或相对路径
lv_label_set_text(label, "This is 思源黑体!");
测试,中文显示成功。
使用点阵字体
矢量字体使用方便,但在资源紧张的MCU中使用,需要消耗一定的内存开销和存储开销,至少需要增加200KB左右的Flash和16KB左右的内存开销。
为了节约内存资源 ,在无需多种字号的情况下,我们通常选择点阵字体。点阵字体可以通过专门的转换工具软件从矢量字库提取。
我们使用里飞网阿里兄提供的免费转换软件实现点阵字体库的转换。
字体转换工具和用法,大家在里飞网论坛自行查阅即可,如不需发贴,无需注册。
生成点阵字库文件的同时,会生成一个C文件,将文件添加到项目,将修改以下方法,增加在Windows系统下的文字字阵数据获取方法实现。
static uint8_t __g_font_buf[512];//如bin文件存在SPI FLASH可使用此buff static uint8_t* __user_font_getdata(int offset, int size) {
//如字模保存在SPI FLASH, SPIFLASH_Read(__g_font_buf,offset,size);
//如字模已加载到SDRAM,直接返回偏移地址即可如:return (uint8_t*)(sdram_fontddr+offset); lv_fs_file_t file;
lv_fs_res_t result;
static uint32_t icount = 0;
result = lv_fs_open(&file, "/Font/Bin/SourceHanSans_16.bin", LV_FS_MODE_RD);
printf("lv_fs_open res:%d,count:%d\r\n", result, ++icount);
if (result != LV_FS_RES_OK)
return NULL; lv_fs_seek(&file, offset, LV_FS_SEEK_CUR);
uint32_t len;
lv_fs_read(&file, __g_font_buf, size, &len);
lv_fs_close(&file); return __g_font_buf;
}
注:此方法仅适用于windows系统中测试使用,如果MCU中使用,速度一定会十分感人^_^,因为lvgl获取点阵字体的每一个字节,都会调用一次这个函数。
大家可对此方法进行优化,如增加读取缓存处理,减少文件访问。如有好的实现,也请告诉我呵。
增加点阵字体测试代码:
void lv_showFont(void)
{
LV_FONT_DECLARE(SourceHanSans_16);//引入字库
lv_obj_t* zh_label = lv_label_create(lv_scr_act());//获取默认屏幕
lv_obj_set_style_text_font(zh_label, &SourceHanSans_16, LV_STATE_DEFAULT);// 设置风格的字体
lv_label_set_text(zh_label, "你好,这是思源黑体!");//显示文字
lv_obj_align(zh_label, LV_ALIGN_TOP_MID, 0, 0); lv_obj_t* label = lv_label_create(lv_scr_act());//获取默认屏幕
lv_obj_set_style_text_font(label, &SourceHanSans_16, LV_STATE_DEFAULT);// 设置风格的字体
lv_label_set_text(label, "山不在高,有仙则名,水不在深,有龙则灵。");//显示文字
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); //lv_obj_t* style_txt = lv_label_create(lv_scr_act());//获取默认屏幕
//lv_obj_set_style_text_font(style_txt, &SourceHanSans_16, LV_STATE_DEFAULT);// 设置风格的字体
//lv_label_set_text(style_txt, "\uF00C确定");//显示文字
//lv_obj_align(style_txt, LV_ALIGN_BOTTOM_MID, 0, 0);
}
运行测试代码,效果如下。
使用图片文件
我们通常希望能够直接使用存储在文件系统中的图片,最好是图片无需预先经过专门的处理,这样的话,图片比较通用,也无需专门的软件工具处理。
LVGL8.3已经准备好了常用的BMP、PNG、JPG格式图像解码器。
考虑解码的性能和速度,我们直接使用BMP位图。
为了降低内存开销和存储开销,我打算使用256色位图,这样的话,一张普通图片,使用windows自带的画图程序,可以直接转存为256色位图。
添加加载图形对象代码,如下
void lv_showBmp(void)
{
lv_obj_t* bmp = lv_img_create(lv_scr_act());
if (bmp == NULL)
{
printf("[%s:%d] create bmp failed\n", __FUNCTION__, __LINE__);
return;
} char* bmp_path;
#if LV_USE_FS_WIN32
bmp_path = "/Images/Lena_320_256.bmp";
#else
bmp_path = "C:/Images/Lena_320_256.bmp";
#endif lv_img_set_src(bmp, bmp_path); // 设置图片
//lv_img_set_zoom(bmp, 128);
lv_obj_align(bmp, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(bmp, 160, 160); // 设置大小
}
此处加载图片的路径应设置成相对路径,且需以’/’开头,文件系统处理函数中,会定位到配置的文件目录里面,否则,会出现找不到文件的情况。
为了节省资源 ,使用256色位图,lv_conf.h中,颜色深度宏参数如下定义
/*Color
depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define
LV_COLOR_DEPTH 8
实际测试,发现存在如上图中的颜色显示不正常问题。
如将色深改为32,#define LV_COLOR_DEPTH 32
使用24位真彩或32位真彩位图,则一切正常,除了lvgl需要的内存大幅飙升(相对于资源紧缺的MCU来说)。
如果想使用16位色深的图片,windows自带的画图工具并不支持,需要专门的工具进行转换,并且需将色深宏参数定义为16。
256色(8位)位图为什么不能正常显示,本人目前也还未找到原因,可能是lvgl的bug,也可能是我打开的姿势不对,如有解决此问题的朋友,请不吝告知,十分感谢。
在Windows模拟器中使用LVGL8.3的更多相关文章
- windows中安装模拟器后修改模拟器中的hosts方法
1.背景 有的时候我们测试安卓的app需要绑定hosts,这个时候我们如果只是修改PC机器上的hosts,然而在模拟器中并不生效.这个时候我们就需要修改模拟器中的hosts. 模拟器中的hosts为只 ...
- monkey工具使用中遇到的问题之一:手机模拟器中的部分应用出现网络无法连接
问题描述: 手机模拟器中的部分应用出现网络无法连接,但是比如:浏览器即可以正常访问网页 解决方法如下: 1.以管理员身份进入到cmd中,以WIN10为例 ,在电脑左下角点击鼠标右键就可以看到 注意: ...
- Android 模拟器中sdcard操作
1. 在模拟器中创建sdcard目录,方法如下: 1. mksdcard命令 用cmd进入SDK的Tools目录,执行mksdcard命令.会出现如下帮助信息 我们可以看到sdcard image支 ...
- ios创建的sqlite数据库文件如何从ios模拟器中导出
为了验证数据库的结构,有的时候需要使用一些管理工具来直接查看sqlite数据库的内容,在windows下有sqlite3的专用工具下载,而在ios下也可以使用火狐浏览器的插件sqlitemanager ...
- iOS学习——如何在mac上获取开发使用的模拟器的资源以及模拟器中每个应用的应用沙盒
如题,本文主要研究如何在mac上获取开发使用的模拟器的资源以及模拟器中每个应用的应用沙盒.做过安卓开发的小伙伴肯定很方便就能像打开资源管理器一样查看我们写到手机本地或应用中的各种资源,但是在iOS开发 ...
- Cmder命令行工具在Windows系统中的配置
一.Cmder简介 Cmder:一款用于Windows系统中,可增强传统cmd命令行工具的控制台模拟器(类似于Linux系统中的终端控制窗口) 特点: 无需安装,解压即用 可使用较多Linux命令,如 ...
- 黑科技抢先尝(续2) - Windows terminal中Powershell Tab的极简美化指南
目录 安装python 安装git 安装powerline字体 主题定制 安装oh-my-posh 查看策略组的执行权限 使用choco 安装终端模拟器 - ConEmu 优化 PowerShell ...
- 在 Windows Phone 中,为 Grid 添加 Tilt 效果
在 Windows Phone 中,Tilt 效果是比较经典的效果,我们可以很简单的为按钮等控件添加这样的效果(使用 Windows Phone Toolkit 的Tilt 效果),但是,如果我们想要 ...
- 如何托管ASP.NET Core应用到Windows Service中
(此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:正在构思一个中间件的设计,考虑是否既可以使用最新的技术,也可以兼顾传统的部署模式.所以有 ...
- xCode5 在ios7模拟器中出现__cxa_throw _pthread_exit错误
xCode5 在ios7模拟器中出现__cxa_throw _pthread_exit错误 2013年10月28日 ⁄ 综合 ⁄ 共 233字 ⁄ 字号 小 中 大 ⁄ 评论关闭 在项目中用模拟器 ...
随机推荐
- 从EDR的火热看安全产品的发展
从EDR的火热看安全产品的发展 2021年4月8日23:13 当开始写这篇博客时,外面正是护网进行得如火如荼的时候.作为一个产品经理,在吃瓜的同时,也在思考着安全产品的发展.这几年一些看得到的变化在深 ...
- 前端实现docx、pdf格式文件在线预览
theme: vuepress highlight: atelier-heath-light 介绍 在业务中,如果遇到文档管理类的功能,会出现需要在线预览的业务需求,本文主要是通过第三方库来实现文档预 ...
- Kubernetes 中部署 MySQL 集群
文章转载自:https://www.cnblogs.com/ludongguoa/p/15319861.html 一般情况下 Kubernetes 可以通过 ReplicaSet 以一个 Pod 模板 ...
- Alermanager_template,email
default.tmpl {{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing ...
- vue-router query和params 传参和接收参数
1.params 方式传递和接收参数 //传参 this.$router.push({ name: 'checkDetailInfo', params:{ fkdNum:fkdNum, jyayStr ...
- 8_Quartz
一. 引言 1.1 简介 Quartz: http://www.quartz-scheduler.org/ 是一个 定时任务调度框架 ,比如我们遇到这样的问题 想在30分钟后, 查看订单是否支付, 未 ...
- mysql工具的使用、增删改查
mysql工具使用 目录 mysql工具使用 mysql的程序组成 mysql工具使用 服务器监听的两种socket地址 mysql数据库操作 DDL操作 数据库操作 表操作 用户操作 查看命令SHO ...
- vulnhub靶场之EMPIRE
准备: 攻击机:虚拟机kali.本机win10. 靶机:EMPIRE: BREAKOUT,地址我这里设置的桥接,下载地址:https://download.vulnhub.com/empire/02- ...
- 齐博x1标签实例:调用多个圈子同时调用相关会员
看这一篇之前,请先看上一篇,因为他们有关联性比如要实现这样的效果 可以通过下面的代码可以实现 {qb:tag name="xxx" type="qun" row ...
- Landau-Vishkin
基础算法 假设我们有两个字符串:,每个字符串由A C G T四个字母组成. 在两个字符串上,都有三种可能的编辑操作(突变): 删除某个字符 在某个位置插入字符 改变某个字符 每一个编辑操作都有惩罚值. ...