目录

准备脚手架

修改源码

对接触摸

测试编译

测试运行


这一节将以一个已经编写好的 lvgl 小游戏 2048 描述如何将已经编写完成的 lvgl 程序移植到开发板上。

准备脚手架

在这之前,我们先准备基础的 LVGL 脚手架。可以直接从 lv_g2d_test 里复制过来进行修改即可。

首先我们复制源码,在 platform/thirdparty/gui/lvgl-8 源码文件夹里,把 红箭头 所指的 lv_g2d_test 的源码作为模板复制到黄箭头指向的 lv_2048 文件夹里。

如下图所示,并清理下 res 资源文件夹,

2022-07-18-13-53-08-1658123584(1).png

同样的,复制一份引索文件,找到 openwrt/package/thirdparty/gui/lvgl-8 并把 lv_g2d_test 复制一份重命名为 lv_2048 作为我们 2048 小游戏使用的引索。

2022-07-18-13-53-55-1658123630(1).png

并编辑 Makefile,修改文件名称,把 lv_g2d_test 修改为这里的 lv_2048

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/package.mk
include ../sunxifb.mkPKG_NAME:=lv_2048
PKG_VERSION:=8.1.0
PKG_RELEASE:=1PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
SRC_CODE_DIR := $(LICHEE_PLATFORM_DIR)/thirdparty/gui/lvgl-8/$(PKG_NAME)
define Package/$(PKG_NAME)SECTION:=guiSUBMENU:=LittlevglCATEGORY:=GuiDEPENDS:=+LVGL8_USE_SUNXIFB_G2D:libuapi +LVGL8_USE_SUNXIFB_G2D:kmod-sunxi-g2d \+LVGL8_USE_FREETYPE:libfreetypeTITLE:=lvgl 2048 
endefPKG_CONFIG_DEPENDS := \CONFIG_LVGL8_USE_SUNXIFB_DOUBLE_BUFFER \CONFIG_LVGL8_USE_SUNXIFB_CACHE \CONFIG_LVGL8_USE_SUNXIFB_G2D \CONFIG_LVGL8_USE_SUNXIFB_G2D_ROTATEdefine Package/$(PKG_NAME)/config
endefdefine Package/$(PKG_NAME)/Default
endefdefine Package/$(PKG_NAME)/descriptiona lvgl 2048 v8.1.0
endefdefine Build/Prepare$(INSTALL_DIR) $(PKG_BUILD_DIR)/$(CP) -r $(SRC_CODE_DIR)/src $(PKG_BUILD_DIR)/$(CP) -r $(SRC_CODE_DIR)/../lvgl $(PKG_BUILD_DIR)/src/$(CP) -r $(SRC_CODE_DIR)/../lv_drivers $(PKG_BUILD_DIR)/src/
endefdefine Build/Configure
endefTARGET_CFLAGS+=-I$(PKG_BUILD_DIR)/srcifeq ($(CONFIG_LVGL8_USE_SUNXIFB_G2D),y)
TARGET_CFLAGS+=-DLV_USE_SUNXIFB_G2D_FILL \-DLV_USE_SUNXIFB_G2D_BLEND \-DLV_USE_SUNXIFB_G2D_BLIT \-DLV_USE_SUNXIFB_G2D_SCALE
endifdefine Build/Compile$(MAKE) -C $(PKG_BUILD_DIR)/src\ARCH="$(TARGET_ARCH)" \AR="$(TARGET_AR)" \CC="$(TARGET_CC)" \CXX="$(TARGET_CXX)" \CFLAGS="$(TARGET_CFLAGS)" \LDFLAGS="$(TARGET_LDFLAGS)" \INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \all
endefdefine Package/$(PKG_NAME)/install$(INSTALL_DIR) $(1)/usr/bin/$(INSTALL_DIR) $(1)/usr/share/lv_2048$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/$(PKG_NAME) $(1)/usr/bin/
endef$(eval $(call BuildPackage,$(PKG_NAME)))

完成脚手架的搭建后,可以 make menuconfig 里查看是否出现了 lv_2048 这个选项,选中它。

2022-07-18-13-56-31-image.png

修改源码

第二步是修改源码。编辑之前复制的 main.c 文件,把不需要的 lv_g2d_test 的部分删去。保留最基础的部分。

#include "lvgl/lvgl.h"
#include "lv_drivers/display/sunxifb.h"
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>static lv_style_t rect_style;
static lv_obj_t *rect_obj;
static lv_obj_t *canvas;int main(int argc, char *argv[]) {lv_disp_drv_t disp_drv;lv_disp_draw_buf_t disp_buf;lv_indev_drv_t indev_drv;uint32_t rotated = LV_DISP_ROT_NONE;lv_disp_drv_init(&disp_drv);/*LittlevGL init*/lv_init();/*Linux frame buffer device init*/sunxifb_init(rotated);/*A buffer for LittlevGL to draw the screen's content*/static uint32_t width, height;sunxifb_get_sizes(&width, &height);static lv_color_t *buf;buf = (lv_color_t*) sunxifb_alloc(width * height * sizeof(lv_color_t), "lv_2048");if (buf == NULL) {sunxifb_exit();printf("malloc draw buffer fail\n");return 0;}/*Initialize a descriptor for the buffer*/lv_disp_draw_buf_init(&disp_buf, buf, NULL, width * height);/*Initialize and register a display driver*/disp_drv.draw_buf = &disp_buf;disp_drv.flush_cb = sunxifb_flush;disp_drv.hor_res = width;disp_drv.ver_res = height;disp_drv.rotated = rotated;disp_drv.screen_transp = 0;lv_disp_drv_register(&disp_drv);evdev_init();lv_indev_drv_init(&indev_drv); /*Basic initialization*/indev_drv.type = LV_INDEV_TYPE_POINTER; /*See below.*/indev_drv.read_cb = evdev_read; /*See below.*//*Register the driver in LVGL and save the created input device object*/lv_indev_t *evdev_indev = lv_indev_drv_register(&indev_drv);/*Handle LitlevGL tasks (tickless mode)*/while (1) {lv_task_handler();usleep(1000);}return 0;
}/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void) {static uint64_t start_ms = 0;if (start_ms == 0) {struct timeval tv_start;gettimeofday(&tv_start, NULL);start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;}struct timeval tv_now;gettimeofday(&tv_now, NULL);uint64_t now_ms;now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;uint32_t time_ms = now_ms - start_ms;return time_ms;
}

接下来则是对接 lv_lib_100ask 与 2048 小游戏,我们先下载 lv_lib_100ask 的源码,放置到 platform/thirdparty/gui/lvgl-8/lv_2048 的 src 文件夹里。并按照 lv_lib_100ask 的说明,复制一份 lv_lib_100ask_conf_template.h 到 src 目录,并改名为 lv_lib_100ask_conf.h

2022-07-18-14-55-44-image.png

编辑 lv_lib_100ask_conf.h,开启整个库的引用,并配置启用 LV_USE_100ASK_2048 。为了简洁,这里删除了不需要的配置项。

/*** @file lv_lib_100ask_conf.h* Configuration file for v8.2.0**/
/** COPY THIS FILE AS lv_lib_100ask_conf.h*//* clang-format off */
#if 1 /*Set it to "1" to enable the content*/ #ifndef LV_LIB_100ASK_CONF_H
#define LV_LIB_100ASK_CONF_H#include "lv_conf.h"/******************** GENERAL SETTING*******************//********************** USAGE*********************/*2048 game*/
#define LV_USE_100ASK_2048                               1
#if LV_USE_100ASK_2048/* Matrix size*//*Do not modify*/#define  LV_100ASK_2048_MATRIX_SIZE          4/*test*/#define  LV_100ASK_2048_SIMPLE_TEST          1
#endif  #endif /*LV_LIB_100ASK_H*/#endif /*End of "Content enable"*/

再编辑 platform/thirdparty/gui/lvgl-8/lv_2048/src/lv_lib_100ask/lv_lib_100ask.h 中的版本号,修改为 (8,1,0)

2022-07-18-15-13-39-image.png

之后在 main.c 里修改,对接 lv_100ask_2048_simple_test,具体如下。

(1)头文件加入 lv_lib_100ask/lv_lib_100ask.h

#include <lv_lib_100ask/lv_lib_100ask.h>

(2)在 main 函数里添加接口调用

lv_100ask_2048_simple_test();

完整的 main.c 如下

#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>#include "lvgl/lvgl.h"
#include "lv_drivers/display/sunxifb.h"
#include "lv_drivers/indev/evdev.h"#include "lv_lib_100ask/lv_lib_100ask.h"  // 引用头文件static lv_style_t rect_style;
static lv_obj_t *rect_obj;
static lv_obj_t *canvas;int main(int argc, char *argv[]) {lv_disp_drv_t disp_drv;lv_disp_draw_buf_t disp_buf;lv_indev_drv_t indev_drv;uint32_t rotated = LV_DISP_ROT_NONE;lv_disp_drv_init(&disp_drv);/*LittlevGL init*/lv_init();/*Linux frame buffer device init*/sunxifb_init(rotated);/*A buffer for LittlevGL to draw the screen's content*/static uint32_t width, height;sunxifb_get_sizes(&width, &height);static lv_color_t *buf;buf = (lv_color_t*) sunxifb_alloc(width * height * sizeof(lv_color_t), "lv_nes");if (buf == NULL) {sunxifb_exit();printf("malloc draw buffer fail\n");return 0;}/*Initialize a descriptor for the buffer*/lv_disp_draw_buf_init(&disp_buf, buf, NULL, width * height);/*Initialize and register a display driver*/disp_drv.draw_buf = &disp_buf;disp_drv.flush_cb = sunxifb_flush;disp_drv.hor_res = width;disp_drv.ver_res = height;disp_drv.rotated = rotated;disp_drv.screen_transp = 0;lv_disp_drv_register(&disp_drv);evdev_init();lv_indev_drv_init(&indev_drv); /*Basic initialization*/indev_drv.type = LV_INDEV_TYPE_POINTER; /*See below.*/indev_drv.read_cb = evdev_read; /*See below.*//*Register the driver in LVGL and save the created input device object*/lv_indev_t *evdev_indev = lv_indev_drv_register(&indev_drv);lv_100ask_2048_simple_test();  // 调用 2048 小游戏/*Handle LitlevGL tasks (tickless mode)*/while (1) {lv_task_handler();usleep(1000);}return 0;
}/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void) {static uint64_t start_ms = 0;if (start_ms == 0) {struct timeval tv_start;gettimeofday(&tv_start, NULL);start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;}struct timeval tv_now;gettimeofday(&tv_now, NULL);uint64_t now_ms;now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;uint32_t time_ms = now_ms - start_ms;return time_ms;
}

然后就是 Makefile 修改,增加一个 lv_lib_100ask 的 SRC 引用。

include lv_lib_100ask/lv_lib_100ask.mk

顺便也把 BIN 改为 lv_2048 ,完整的 Makefile 如下

#
# Makefile
#
CC ?= gcc
LVGL_DIR_NAME ?= lvgl
LVGL_DIR ?= ${shell pwd}
CFLAGS ?= -O3 -g0 -I$(LVGL_DIR)/ -Wall -Wshadow -Wundef -Wmissing-prototypes -Wno-discarded-qualifiers -Wall -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wno-error=cpp -Wuninitialized -Wmaybe-uninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion -Wclobbered -Wdeprecated -Wempty-body -Wtype-limits -Wshift-negative-value -Wstack-usage=2048 -Wno-unused-value -Wno-unused-parameter -Wno-missing-field-initializers -Wuninitialized -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wpointer-arith -Wno-cast-qual -Wmissing-prototypes -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wno-discarded-qualifiers -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare
LDFLAGS ?= -lm
BIN = lv_2048#Collect the files to compile
SRCDIRS   =  $(shell find . -maxdepth 1 -type d)
MAINSRC = $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c))include $(LVGL_DIR)/lvgl/lvgl.mk
include $(LVGL_DIR)/lv_drivers/lv_drivers.mk
include lv_lib_100ask/lv_lib_100ask.mkOBJEXT ?= .oAOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))MAINOBJ = $(MAINSRC:.c=$(OBJEXT))SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
OBJS = $(AOBJS) $(COBJS)## MAINOBJ -> OBJFILESall: default%.o: %.c@$(CC)  $(CFLAGS) -c $< -o $@@echo "CC $<"default: $(AOBJS) $(COBJS) $(MAINOBJ)$(CC) -o $(BIN) $(MAINOBJ) $(AOBJS) $(COBJS) $(LDFLAGS)clean: rm -f $(BIN) $(AOBJS) $(COBJS) $(MAINOBJ)

对接触摸

做了以上操作,可能会发现触摸没有反应,这是因为触摸绑定的 event 事件号不对,默认的绑定是 event3 而查阅启动 log 可知,开发板的触摸屏对接的是 event0

2022-07-18-15-17-48-image.png

这时需要修改绑定的 event 事件号,其配置文件在 lv_drv_conf.h 内:

2022-07-18-15-19-12-image.png

这里将 event3 改为 event0 即可

#  define EVDEV_NAME   "/dev/input/event0"

当然除了这样的方法,另外也可以用命令生成软连接 touchscreen,就会直接以 touchscreen 为触摸节点,方便调试:

ln -s /dev/input/eventX /dev/input/touchscreen

测试编译

修改好了,希望单独编译这个包测试下而不编译完整的 SDK。可以这样做:

(1)确保已经 source build/envsetup.sh 并已经 lunch

(2)在任意文件夹下执行命令 mmo lv_2048 -B

其中 mmo 的意思是 单独编译一个 openWrt 软件包,后面的 lv_2048 是软件包名。-B 参数是先 clean 再编译,不加这个参数就是直接编译了。

测试运行

编译打包后,到开发板上使用 lv_2048 即可运行

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

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

相关文章

在Unity2021中使用Profiler的Deep Profile功能时内存超高怎么办?

这通常是因为Deep Profile会记录每一帧所有函数调用的详细信息&#xff0c;导致内存急剧增长&#xff0c;尤其在大型项目或复杂场景中4。别担心&#xff0c;我来帮你分析原因并提供一些解决办法。 理解 Deep Profile 的内存开销与替代方案 Deep Profile是Unity Profiler的一个…

Ubuntu 设置中文输入法

一、使用 IBus&#xff08;Ubuntu 默认框架&#xff09;步骤 1&#xff1a;安装中文输入法sudo apt install ibus-libpinyin ibus-pinyin步骤 2&#xff1a;添加输入法打开 Settings > Keyboard > Input Sources。点击 “”&#xff0c;搜索 Chinese (Intelligent Pinyin…

【Zephyr电源与功耗专题】14_BMS电池管理算法(三重验证机制实现高精度电量估算)

文章目录前言一、算法系统框架设计介绍1.1&#xff1a;核心设计方式1.2&#xff1a;系统架构图1.3&#xff1a;核心参数配置二、核心算法详解2.1&#xff1a;硬件数据采集与滤波2.2&#xff1a;三重算法机制2.2.1&#xff1a;库仑计法&#xff08;电流积分&#xff09;2.2.2&am…

Python网络与多任务编程:TCP/UDP实战指南

Python网络与多任务编程&#xff1a;TCP/UDP实战指南 一、网络编程 1.1 前言 网络编程是现代软件开发中不可或缺的一部分&#xff0c;它使得不同设备之间的数据交换成为可能。Python提供了强大的标准库来支持各种网络编程需求。 1.1.1 IP地址简介 IP地址是互联网上设备的唯一标…

Android8 binder源码学习分析笔记(四)——ServiceManager启动

前文回顾&#xff1a; Android8 binder源码学习分析笔记&#xff08;三&#xff09;&#xff1a; https://blog.csdn.net/g_i_a_o_giao/article/details/151365630?spm1001.2014.3001.5502 Android8 binder源码学习分析笔记&#xff08;二&#xff09;&#xff1a; https://…

Redis 大 Key 与热 Key:生产环境的风险与解决方案

&#x1f525; Redis 大 Key 与热 Key&#xff1a;生产环境的风险与解决方案 文章目录&#x1f525; Redis 大 Key 与热 Key&#xff1a;生产环境的风险与解决方案&#x1f9e0; 一、问题定义与识别&#x1f4a1; 什么是大 Key&#xff1f;&#x1f525; 什么是热 Key&#xff…

C++算法题中的输入输出形式(I/O)

本文主要帮助刷leetcode题型快速适应完整带输入输出的题&#xff08;机试、考试、比赛等&#xff09;接收能用cin就用cin 。cin 自动分割单词 的特性&#xff08;cin 读取字符串时会自动跳过空格 / 换行&#xff0c;将连续非空格字符作为一个 “单词”&#xff09;一、单组输入…

【左程云算法09】栈的入门题目-最小栈

目录 栈的入门题目-最小栈 代码演示 视频链接 算法讲解015【入门】栈的入门题目-最小栈 Leecode155 栈的入门题目-最小栈 实现一个getmin方法&#xff08;高效方法&#xff0c;即不用遍历&#xff09;&#xff0c;希望能实现O&#xff08;1&#xff09; 做法&#xff1a…

Grafana与Prometheus实战

&#x1f31f;Grafana的Dashboard的权限管理 创建团队 创建用户 设置团队权限 &#x1f31f;Prometheus启用https及认证功能 自建ca的证书 准备证书目录 mkdir /app/tools/prometheus-2.53.4.linux-amd64/certs cd /app/tools/prometheus-2.53.4.linux-amd64/certs生成ca的…

FPGA交通灯设计报告(源码+管脚约束+实物图+设计报告)

基于FPGA的交通灯设计 摘要 本设计采用FPGA技术实现了一个智能交通灯控制系统。系统以Verilog HDL为设计语言,在FPGA平台上实现了交通灯的自动控制、数码管倒计时显示、紧急情况处理等功能。通过合理的状态机设计和模块化编程,系统具有良好的实时性、可靠性和可扩展性,能够…

技术论文分析分析论文《计算机病毒判定专家系统原理与设计》思考其在游戏中的应用

论文原文的引言主要有两大部分的内容&#xff1a;介绍计算机病毒&#xff0c;明确本文使用的病毒分类方式&#xff1b;分析传统计算机病毒检测存在的弊端。对于计算机病毒的定义&#xff0c;文中给出的定义比较严谨&#xff0c;我自己查了一下现在百度百科的定义&#xff0c;两…

《Unity项目实战:动态加载引发的显存危机全链路排查与重构实践》

从动态光影那流光溢彩、仿佛赋予虚拟世界真实质感的绚丽效果—这得益于Unity引擎强大的HDRP管线对光照路径的精准模拟,到物理引擎驱动的物体碰撞精准到毫厘的物理反馈—依托Unity Physics模块对刚体动力学的毫秒级计算,再到能够依据不同设备性能自动适配的画质表现—通过Unit…

智慧水库综合管理系统平台御控物联网解决方案

一、行业背景与痛点分析水库作为防洪、灌溉、供水、发电及生态保护的核心基础设施&#xff0c;其管理效率直接关系到区域水资源安全与可持续发展。然而&#xff0c;传统水库管理模式存在四大核心痛点&#xff1a;数据孤岛严重&#xff1a;水位、雨量、水质、设备状态等数据分散…

使用nvm安装Node.js18以下报错解决方案——The system cannot find the file specified.

使用 nvm 安装 Node.js 18以下 报错解决方案 在前端开发过程中&#xff0c;常常需要针对不同项目切换 Node.js 版本。nvm&#xff08;Node Version Manager&#xff09;是最常用的工具。但最近在尝试安装 Node.js 14 版本时&#xff0c;遇到了奇怪的错误。 问题描述 使用 nv…

在Excel和WPS表格中快速复制上一行内容

有的时候我们在Excel和WPS表格中想复制上一行对应单元格、连续区域或整行的内容&#xff0c;只需要在当前行拖动鼠标左键选中相关区域&#xff0c;然后按CtrlD键即可将上一行对应位置的内容复制过来——需要注意的是&#xff0c;如果当前行有数据&#xff0c;这些数据会直接被覆…

408学习之c语言(递归与函数)

今天主要学习了递归与函数的相关内容&#xff0c;下面将我今天所学知识与所写代码分享给大家 递归核心要点 递归三要素 基准条件&#xff08;明确终止条件&#xff09; 递归调用&#xff08;逐步分解问题&#xff09; 收敛性&#xff08;确保每次递归都向基准条件靠近&#xff…

swVBA自学笔记016、Solidworks API Help 帮助文档的(三大版块)

目录1. Namespace (命名空间) 版块2. Interface (接口) 版块3. Members (接口成员) 版块4、总结关系5、如果你感觉上面说的过于简单&#xff0c;请往下看!6、示例链接→SOLIDWORKS API Help 20197、需要注意的是&#xff0c;带“I”的对象表示&#xff1a;接口1. Namespace (命…

通俗易懂地讲解JAVA的BIO、NIO、AIO

理解Java的I/O模型&#xff08;BIO、NIO、AIO&#xff09;对于构建高性能网络应用至关重要 &#x1f9e0; 通俗理解&#xff1a;快递站的故事 想象一个快递站&#xff1a; • BIO&#xff1a;就像快递站为每一个包裹都安排一位专员。专员从接到包裹到处理完&#xff08;签收、…

LabVIEW 泵轮检测系统

在汽车行业&#xff0c;泵轮作为液力变矩器关键部件&#xff0c;其质量检测极为重要。传统手工检测泵轮效率低且误差大&#xff0c;为此构建基于 LabVIEW 与西门子硬件结合的泵轮检测系统。 应用场景 聚焦汽车零部件生产车间&#xff0c;对泵轮总成进行出厂前检测。在液力变矩…

2025年8月月赛 T2 T3

一. 七天假日 T2原思路&#xff1a;直接计算左右括号的数量&#xff0c;然后直接输出他们的差改进思路&#xff1a; 用d值记录截止到当前位置&#xff0c;还需要多少个右括号可以满足非法要求cur&#xff1a;截止到当前位置&#xff0c;已经有多少个右括号sum是右括号位置的前缀…