当前位置: 首页 > news >正文

在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版本必须要这样设置。

相关文章:

在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) 拉取代码到本地硬盘&…...

2023第十四届蓝桥杯国赛 C/C++ 大学 B 组

文章目录 前言试题 A: 子 2023作者思考题解答案 试题 B: 双子数作者思考题解 试题 C: 班级活动作者思考题解 试题 D: 合并数列作者思考题解 试题 E: 数三角作者思考题解 试题 F: 删边问题作者思考题解 试题 G: AB 路线作者思考题解 试题 H: 抓娃娃作者思考题解 试题 I: 拼数字试…...

如何在页面中加入百度地图

官方文档&#xff1a;jspopularGL | 百度地图API SDK (baidu.com) 添加一下代码就可以实现 <!DOCTYPE html> <html> <head><meta name"viewport" content"initial-scale1.0, user-scalableno"/><meta http-equiv"Conten…...

Windows VC++提升当前进程权限到管理员权限

Windows VC提升当前进程权限 Windows VC提升当前进程权限到管理员权限 Windows VC提升当前进程权限到管理员权限 有时候Windows下我们需要提升当前进程的权限到管理员权限&#xff0c;相关VC代码如下&#xff1a; #ifndef SAFE_CLOSE_HANDLE #define SAFE_CLOSE_HANDLE(handl…...

算法leetcode|92. 反转链表 II(rust重拳出击)

文章目录 92. 反转链表 II&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a;进阶&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 92. 反转链表 II&#xff1a; 给你单链表的…...

Chapter 7 - 3. Congestion Management in Ethernet Storage Networks以太网存储网络的拥塞管理

Pause Threshold for Long Distance Links长途链路的暂停阈值 This section uses the following basic concepts: 本节使用以下基本概念: Bit Time (BT): It is the time taken to transmit one bit. It is the reciprocal of the bit rate. For example, BT of a 10 GbE po…...

优雅玩转实验室服务器(二)传输文件

使用服务器最重要的肯定是传输文件了&#xff0c;我们不仅需要本地的一些资源上传到服务器&#xff0c;好进行实验&#xff0c;也需要将服务器计算得到的实验结果传输到本地&#xff0c;来进行预览或者报告撰写。 首先&#xff0c;由于涉及到服务器操作&#xff0c;我强烈推荐…...

动态面板简介以及ERP原型图案列

动态面板简介以及ERP原型图案列 1.Axure动态面板简介2.使用Axure制作ERP登录界面3.使用Asure完成左侧菜单栏4.使用Axuer完成公告栏5.使用Axuer完成左边侧边栏 1.Axure动态面板简介 在Axure RP中&#xff0c;动态面板是一种强大的交互设计工具&#xff0c;它允许你创建可交互的…...

漏刻有时百度地图API实战开发(12)(切片工具的使用、添加自定义图层TileLayer)

TileLayer向地图中添加自定义图层 var tileLayer new BMap.TileLayer();tileLayer.getTilesUrl function (tileCoord, zoom) {var x tileCoord.x;var y tileCoord.y;return images/tiles/ zoom /tile- x _ y .png;}var lockMap new BMap.MapType(lock_map, tileLaye…...

python 爬虫 m3u8 视频文件 加密解密 整合mp4

文章目录 一、完整代码二、视频分析1. 认识m3u8文件2. 获取密钥&#xff0c;构建解密器3. 下载ts文件4. 合并ts文件为mp4 三、总结 一、完整代码 完整代码如下&#xff1a; import requests from multiprocessing import Pool import re import os from tqdm import tqdm fro…...

mybatis中xml文件容易搞混的属性

目录 第一章、1.1&#xff09;MyBatis中resultMap标签1.2&#xff09;MyBatis的resultType1.3&#xff09;MyBatis的parameterType1.4&#xff09;type属性1.5&#xff09;jdbcType属性1.6&#xff09;javaType属性1.7&#xff09;ofType属性 友情提醒: 先看文章目录&#xff…...

android Retrofit2.0请求 延长超时操作

import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory;public class MyApiClient {private static final String BASE_URL "https://api.example.com/";// 创建 OkHttpClient&#xff0c;并设置超时时间…...

Axure之动态面板轮播图

目录 一.介绍 二.好处 三.动态面板轮播图 四.动态面板多方式登录 五.ERP登录 六.ERP的左侧菜单栏 七.ERP的公告栏 今天就到这了哦&#xff01;&#xff01;&#xff01;希望能帮到你了哦&#xff01;&#xff01;&#xff01; 一.介绍 Axure中的动态面板是一个非常有用的组…...

一文读懂算法中的时间复杂度和空间复杂度,O(1)、O(logn)、O(n)、O(n^2)、O(2^n) 附举例说明,常见的时间复杂度,空间复杂度

时间复杂度和空间复杂度是什么 时间复杂度&#xff08;Time Complexity&#xff09;是描述算法运行时间长短的一个度量。空间复杂度&#xff08;Space Complexity&#xff09;是描述算法在运行过程中所需要的存储空间大小的一个度量。 时间复杂度和空间复杂度是衡量算法性能…...

LWIP热插拔功能实现

0 工具准备 1.lwip 1.4.1 2.RTOS&#xff08;本文使用rt-thread&#xff09;1 使能连接变化回调功能 打开lwipopts.h&#xff0c;将宏定义LWIP_NETIF_LINK_CALLBACK的值设为1&#xff0c;如下&#xff1a; #define LWIP_NETIF_LINK_CALLBACK 1这个宏定义被使能后会将…...

android下的app性能测试应主要针对那些方面,如何开展?

如何开展安卓手机下的App性能测试&#xff0c;对于优秀的测试人员而言&#xff0c;除了要懂得性能测试的步骤流程外&#xff0c;还应该懂的性能测试的一些其他知识&#xff0c;比如性能测试指标、各指标的意义&#xff0c;常用的性能测试工具、如何查看结果分析等等知识。所以本…...

【深度学习】注意力机制(二)

本文介绍一些注意力机制的实现&#xff0c;包括EA/MHSA/SK/DA/EPSA。 【深度学习】注意力机制&#xff08;一&#xff09; 【深度学习】注意力机制&#xff08;三&#xff09; 目录 一、EA&#xff08;External Attention&#xff09; 二、Multi Head Self Attention 三、…...

学习黑马vue

项目分析 项目下载地址&#xff1a;vue-admin-template-master: 学习黑马vue 项目下载后没有环境可参考我的篇文章&#xff0c;算是比较详细&#xff1a;vue安装与配置-CSDN博客 安装这两个插件可格式化代码&#xff0c;vscode这个软件是免费的&#xff0c;官网&#xff1a;…...

gdb本地调试版本移植至ARM-Linux系统

移植ncurses库 本文使用的ncurses版本为ncurses-5.9.tar.gz 下载地址&#xff1a;https://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz 1. 将ncurses压缩包拷贝至Linux主机或使用wget命令下载并解压 tar-zxvf ncurses-5.9.tar.gz 2. 解压后进入到ncurses-5.9目录…...

《Linux C编程实战》笔记:实现自己的ls命令

关键函数的功能及说明 1.void display_attribute(struct stat buf,char *name) 函数功能&#xff1a;打印文件名为name的文件信息&#xff0c;如 含义分别为&#xff1a;文件的类型和访问权限&#xff0c;文件的链接数&#xff0c;文件的所有者&#xff0c;文件所有者所属的组…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

6.9-QT模拟计算器

源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...

基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)

注&#xff1a;文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件&#xff1a;STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...