在windows系统搭建LVGL模拟器(codeblock工程)

1.codeblock准备

下载codeblock(mingw),安装。可参考网上教程。

2.pc_simulator_win_codeblocks 工程获取

仓库地址:lvgl/lv_port_win_codeblocks: Windows PC simulator project for LVGL embedded GUI Library (github.com)

 拉取代码到本地硬盘,如下操作步骤:

# 打开git终端输入下面地址并回车
git clone https://github.com/lvgl/lv_sim_codeblocks_win.git# 进入文件夹lv_sim_codeblocks_win 
cd lv_sim_codeblocks_win # 执行下面命令拉取子模块并初始化仓库
git submodule update --init --recursive# 文件夹介绍:
# lvgl:lvgl源代码# lv_examples:lvgl 的使用例程(各种控件使用例程,布局使用例程,系统API使用例程,第三方库使用例程...)# lv_demo:官方给的比较综合的demo示例# lv_drivers:和平台相关的底层驱动

如下图:

LittlevGL.cbp 就是codeblock工程。

我拉取的LVGL 是V9 版本。

3.编译工程

打开codeblock,选择工程,【File】-【Open】如下图:

设置编译器,【Settings】-【Compiler...】,如下图:

执行【Auto-detect】,或者选取自己的mingw编译器路径,我使用的是QT5自带的编译器

编译并运行,如下图:

等待一段时间,一个默认的demo编译好后自动运行界面如下:

本篇文章不具体讲解LVGL控件使用,可自行在网上找教程,或使用官方教程文档。

4.使用LVGL V9 文件系统报错问题排查

下面我记录下,使用LVGL访问文件系统出现的问题,我一开始参考的教程是百问网的LVGL教程,他使用的LVGL是V8版本,所以我参照教程使用一直报 “未知错误”

LVGL默认支持4种文件系统 分别是 LV_USE_FS_STDIO ,LV_USE_FS_POSIX,LV_USE_FS_WIN32,LV_USE_FS_FATFS

我们使用windows 平台我选择 LV_USE_FS_WIN32 ,对应的底层文件操作都是windows自带的,所以不需要移植了。

在lv_conf.h中打开配置如下:

我挂载到D盘,工作目录 LV_FS_WIN32_PATH ""  不配置。

示例代码如下:

#define FILE_NAME "D:/example/example.txt"
void lv_chenbo_demo_fs(void)
{
#if 1lv_fs_file_t f;lv_fs_res_t res;res = lv_fs_open(&f, FILE_NAME, LV_FS_MODE_RD);if(res != LV_FS_RES_OK) {LV_LOG_USER("open file error:%d!", res);return;}uint32_t read_num;uint8_t buf[32];memset(buf,0x0,sizeof buf);res = lv_fs_read(&f, buf, 32, &read_num);if(res != LV_FS_RES_OK) {LV_LOG_USER("read file error!");}printf("read content:\n%s", buf);lv_fs_close(&f);
#endif
}

我在D盘创建文件  example/example.txt

编译运行:

一直报错打开文件失败,错误代码12

跳转到 lv_fs.c 中的 lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode)函数如下:

lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode)
{if(path == NULL) {LV_LOG_WARN("Can't open file: path is NULL");return LV_FS_RES_INV_PARAM;}char letter = path[0];lv_fs_drv_t * drv = lv_fs_get_drv(letter);if(drv == NULL) {LV_LOG_WARN("Can't open file (%s): unknown driver letter", path);return LV_FS_RES_NOT_EX;}if(drv->ready_cb) {if(drv->ready_cb(drv) == false) {LV_LOG_WARN("Can't open file (%s): driver not ready", path);return LV_FS_RES_HW_ERR;}}if(drv->open_cb == NULL) {LV_LOG_WARN("Can't open file (%s): open function not exists", path);return LV_FS_RES_NOT_IMP;}const char * real_path = lv_fs_get_real_path(path);void * file_d = drv->open_cb(drv, real_path, mode);if(file_d == NULL || file_d == (void *)(-1)) {return LV_FS_RES_UNKNOWN;}file_p->drv = drv;file_p->file_d = file_d;if(drv->cache_size) {file_p->cache = lv_malloc(sizeof(lv_fs_file_cache_t));LV_ASSERT_MALLOC(file_p->cache);lv_memzero(file_p->cache, sizeof(lv_fs_file_cache_t));file_p->cache->start = UINT32_MAX;  /*Set an invalid range by default*/file_p->cache->end = UINT32_MAX - 1;}return LV_FS_RES_OK;
}

这个函数是LVGL提供的是一个抽象的文件操作API,他根据不同的文件系统去调用更底层的文件系统接口。

问题出在这里:

    const char * real_path = lv_fs_get_real_path(path);void * file_d = drv->open_cb(drv, real_path, mode);if(file_d == NULL || file_d == (void *)(-1)) {return LV_FS_RES_UNKNOWN;}

看下static const char * lv_fs_get_real_path(const char * path) 函数

/*** Skip the driver letter and the possible : after the letter* @param path path string (E.g. S:/folder/file.txt)* @return pointer to the beginning of the real path (E.g. /folder/file.txt)*/
static const char * lv_fs_get_real_path(const char * path)
{path++; /*Ignore the driver letter*/if(*path == ':') path++;return path;
}

它的功能就是获取路径 : 后面的字符地址,也就是他把盘符D: 去掉了。

drv->open_cb()是一个回调函数,我们使用是WIN32平台的文件系统所以看

lv_fs_win32.c 中的static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)

函数如下:

/*** Open a file* @param drv pointer to a driver where this function belongs* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR* @return pointer to FIL struct or NULL in case of fail*/
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{LV_UNUSED(drv);DWORD desired_access = 0;if(mode & LV_FS_MODE_RD) {desired_access |= GENERIC_READ;}if(mode & LV_FS_MODE_WR) {desired_access |= GENERIC_WRITE;}/*Make the path relative to the current directory (the projects root folder)*/char buf[MAX_PATH];lv_snprintf(buf, sizeof(buf), LV_FS_WIN32_PATH "%s", path);return (void *)CreateFileA(buf,desired_access,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
}

看下面代码(重点):

    char buf[MAX_PATH];lv_snprintf(buf, sizeof(buf), LV_FS_WIN32_PATH "%s", path);

这个功能是:把我们传过来的路径(前面已经去掉D:) 然后和 LV_FS_WIN32_PATH 拼接在一起,还记得之前这个宏定义我们设置的是空字符串"",这样拼成的新的路径传递给windows底层API使用,造成的结果就是路径错误("/example/examle.txt")。

所以我们就算不配置工作路径,也要把盘符设置一下:

/*API for CreateFile, ReadFile, etc*/
#define LV_USE_FS_WIN32 1
#if LV_USE_FS_WIN32#define LV_FS_WIN32_LETTER 'D'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/#define LV_FS_WIN32_PATH "D:"         /*Set the working directory. File/directory paths will be appended to it.*/#define LV_FS_WIN32_CACHE_SIZE 1024   /*>0 to cache this number of bytes in lv_fs_read()*/
#endif

这样编译,在运行:

D:/example/example.txt 文件中的 hello,world 被读取出来并显示。

注意:我实际测试的LVGL V9版本必须要这样设置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/277079.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

攻防世界题目练习——Web引导模式(五)(持续更新)

题目目录 1. FlatScience2. bug3. Confusion1 1. FlatScience 参考博客: 攻防世界web进阶区FlatScience详解 题目点进去如图,点击链接只能看到一些论文pdf 用dirsearch和御剑扫描出一些隐藏文件: robots.txt: admin.php: login.php: f…

影视视频+知识付费行业万能通用响应式网站系统源码 三网合一 带完整的安装部署教程

互联网的快速发展,网络视频和知识付费行业也迎来了前所未有的发展机遇。为了满足这一市场的需求,基于响应式网站技术的万能通用影视视频知识付费行业网站系统便由此应运而生。本系统集成了三网合一的解决方案,旨在帮助用户快速搭建高品质、高…

flutter的SingleChildScrollView控件详解

文章目录 SingleChildScrollView的介绍和使用场景详细介绍 SingleChildScrollView的介绍和使用场景 SingleChildScrollView 是 Flutter 中的一个小部件,用于创建一个可滚动的单个子部件。它通常用于处理内容超出屏幕可见区域的情况,允许用户通过滚动来查…

2024年视频监控行业发展趋势预测及EasyCVR视频分析技术应用

随着技术的改进,视频监控领域在过去十年迅速发展。与此同时,该行业正在通过先进创新技术(如人工智能和云计算等技术)的积极商业化,获得了新的增长机会。视频监控系统不再仅仅用于记录图像,而是已经成为全球…

3. cgal 示例 GIS (Geographic Information System)

GIS (Geographic Information System) 地理信息系统 原文地址: https://doc.cgal.org/latest/Manual/tuto_gis.html GIS 应用中使用的许多传感器(例如激光雷达)都会生成密集的点云。此类应用程序通常利用更先进的数据结构:例如,不…

学习使用echarts漏斗图的参数配置和应用场景

学习使用echarts漏斗图的参数配置和应用场景 前言什么是漏斗图漏斗图的特点及应用场景漏斗图的特点漏斗图常见的的应用场景: echarts中漏斗的常用属性echart漏斗代码美化漏斗图样式1、设置标题字体大小2、设置标签样式3、设置漏斗图为渐变颜色4、设置高亮效果5、设置…

速学数据结构 | 树 森林 二叉树 的概念详讲篇

🎬 鸽芷咕:个人主页 🔥 个人专栏:《速学数据结构》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 📋 前言 🌈hello! 各位宝子们大家好啊,关于线性表我们已经在前面更新完了…

MES安灯管理:优化生产监控的重要工具

一、MES安灯管理的概念 MES安灯管理是一种基于物理安灯和数字化管理的生产异常管理工具。它通过物理安灯和数字化系统的结合,实现对生产异常的实时监控和及时反馈,从而帮助企业快速响应和解决生产异常,提高生产效率和产品质量。 二、MES系统…

mysql:通过INFORMATION_SCHEMA数据库查询表的元信息

使用SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA database_name AND TABLE_NAME table_name;查询某个表的元信息。其中database_name替换为数据库名称,table_name替换为表的名称。 例如,下面语句,查询development数据库中…

【C++初阶】类与对象(上)

类与对象(上) 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1 访问限定符4.2 封装 5.类的作用域6.类的实例化7.类对象模型7.1 如何计算类对象的大小7.2 结构体内存对齐规则 8.this指针8.1 this指针的引出8.2 this指针的特性…

前端必备-http知识

在掘金查看该文章 计算机网络五层模型 1.物理层 (Physical Layer) 关键词 光纤,电缆,双绞线,连接 物理层要解决的主要问题: (1)物理层要尽可能地屏蔽掉物理设备和传输媒体,通信手段的不同,使数据链路层感觉不到这些…

2023 re:Invent使用 PartyRock 和 Amazon Bedrock 安全高效构建 AI 应用程序

前言 本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 亚马逊云科技开发者社区, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 “Your Data, Your AI, Your Future.(你的数据,你的AI&…