- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
之前有记录过在 esp32 中使用 LVGL 的笔记,需要的小伙伴可以了解一下, esp-idf 移植 lvgl8.3.3 我之前整理的学习资料: https://www.cnblogs.com/jzcn/p/16647106.html 。
开发板:一块 linux 的开发板 或 linux 的虚拟机 lvgl:8.3.3 系统:ubuntu 18.04 。
注意: 在 linux 环境下使用 lvgl 就相对比较简单了,这里记录了两个方式.
因为 linux 环境下,官方已经简历好项目的,所以只需要直接拉取就好了。 仓库地址: https://github.com/lvgl/lv_port_linux_frame_buffer 。
git 命令 。
git clone --recursive https://github.com/lvgl/lv_port_linux_frame_buffer.git
# 如果拉取不下来,可以使用下面的加速地址,我也不知道是否会失效
https://github.moeyy.xyz/https://github.com/lvgl/lv_port_linux_frame_buffer.git
注意: 拉取的时候已经要加 --recursive ,否则项目中的子工程拉不下来,如果拉取时忘记加 --recursive 参数,可以在拉取完成是使用 git submodule update --init --recursive 命令更新一下即可.
工程目录 拉取完成后,工程目录如下所示:
编译工程 直接使用 make 命令编译即可,完成后如下图所示:会直接生成可执行文件,如下图所示:
注意: 发现可执行文件后,基本就完成了,直接运行即可, ./demo ,毫无疑问基本会运行失败,结果如下图所示:
修改显示驱动 这里的显示驱动都是使用的 Framebuffer 缓冲区,我之间有个简单的笔记使用,不了解的小伙伴,可以看我之前的笔记, Linux Framebuffer 实验 ,知道自己的缓冲区设备后,就可以直接在文件 lv_drv_conf.h 中进行修改,不过多数情况下都是 /dev/fb0 可以不用修改,如下图所示:
修改鼠标或触摸驱动 在修改鼠标或触摸驱动时,需要借助 evtest 工具,找到自己设备的输入事件.
安装 evtset 工具 。
sudo apt-get install evtest
使用命令 sudo evtest 找到对应的事件编号,如下图所示:
找到鼠标事件后,直接在 lv_drv_conf.h 文件中,更改对应的事件编号即可,如下图所示:
运行测试 完成驱动修改后,重新编译测试,因为使用的是 Framebuffer 缓冲区,所以在 ubuntu 缓冲区中使用是,需要关闭图形显示后,才是正常使用 Framebuffer ,命令如下 。
# 关闭图形显示
systemctl set-default multi-user.target
reboot
# 打开图形显示
systemctl set-default graphical.target
reboot
关闭图形显示后,测试结果如下图所示:
上面我们已经完成了,在 ubuntu 中测试 LVGL 操作还是比较简单的,现在我们开始尝试手动创建工程,并将编译后生成的.o文件放到指定目录下,然后更改编译工具,使其在arm开发板中进行使用.
注意: 在创建过程中,有什么问题可以直接参考上面的工程,可以解决我们过程中遇到的问题 。
下载 LVGL 。
创建工程目录 这里我就不详细说明了,直接上图,只要文件目录如图所示一样即可,路径图下图所示:
将 lvgl 移动到 lib 文件下,并删除多余的文件,如下图所示: 注意: 其中的 lv_conf.h 文件是直接将 lv_conf_template.h 拷贝后进行重命名的,完成后将文件中的 #if 0 改为 #if 1 。
将 lvgl 目录下的 demos 文件拷贝到 lib 文件下,如下图所示: 注意: 这里为了 demos 使用中减少问题,我直接拷贝了 lvgl 文件下的 demos 并重命名为 lv_demos 。
将 lv_drivers 拷贝到 lib 文件下,并删除多余的文件,如下图所示: 注意: 其中 lv_drv_conf.h 文件是拷贝 lv_drv_conf_template.h 文件重命名后得到的,完成后将文件中的 #if 0 改为 #if 1 。
将 lvgl 目录下的 examples 文件拷贝到 lib 文件下,如下图所示:
在 application 文件下创建 main.c 文件,内容如下:
#include "lvgl.h"
#include "../lib/lv_demos/lv_demos.h"
#include "../lib/lv_drivers/display/fbdev.h"
#include "../lib/lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#define DISP_BUF_SIZE (128 * 1024)
int main(void)
{
/*LittlevGL init*/
lv_init();
/*Linux frame buffer device init*/
fbdev_init();
/*A small buffer for LittlevGL to draw the screen's content*/
static lv_color_t buf[DISP_BUF_SIZE];
/*Initialize a descriptor for the buffer*/
static lv_disp_draw_buf_t disp_buf;
lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);
/*Initialize and register a display driver*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &disp_buf;
disp_drv.flush_cb = fbdev_flush;
disp_drv.hor_res = 800;
disp_drv.ver_res = 480;
lv_disp_drv_register(&disp_drv);
evdev_init();
static lv_indev_drv_t indev_drv_1;
lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
indev_drv_1.type = LV_INDEV_TYPE_POINTER;
/*This function will be called periodically (by the library) to get the mouse position and state*/
indev_drv_1.read_cb = evdev_read;
lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);
/*Set a cursor for the mouse*/
LV_IMG_DECLARE(mouse_cursor_icon)
lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/
/*Create a Demo*/
lv_demo_widgets();
/*Handle LitlevGL tasks (tickless mode)*/
while(1) {
lv_timer_handler();
usleep(5000);
}
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;
}
拷贝鼠标文件 mouse_cursor_icon.c 将方式一中获取到的鼠标文件拷贝到 application 文件下 。
在 lib 目录下创建 lib.mk 文件,内容如下:
##################################### lvgl库 #####################################
# 文件路径
LVGL_DIR ?= $(PROJECT_PATH)/lib
# 所需的宏定义
CFLAGS += -DLV_CONF_INCLUDE_SIMPLE
CFLAGS += -DLV_LVGL_H_INCLUDE_SIMPLE
# lvgl库
LVGL_DIR_NAME ?= lvgl
# 所需头文件的路径
CFLAGS += -I$(LVGL_DIR)/lvgl
# 收集需要编译的源文件
include $(LVGL_DIR)/lv_demos/lv_demos.mk
include $(LVGL_DIR)/lv_examples/lv_examples.mk
include $(LVGL_DIR)/lv_drivers/lv_drivers.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/lvgl.mk
在主目录下创建 Makefile 文件,内容如下:
#
# Makefile
# 编译的.o文件和.c文件在同一路径下
#
$(info "start...")
# 可执行文件名
PROJECT_NAME = lvgl_app
##################################### 项目路径 #####################################
PROJECT_PATH ?= ${shell pwd}
OBJ_DIR := $(PROJECT_PATH)/build
##################################### 设置编译器,默认使用GCC #####################################
CC = arm-linux-gnueabihf-gcc
CC ?= gcc
##################################### 所需头文件的路径 #####################################
# lv_conf.h
CFLAGS += -I$(PROJECT_PATH)/lib/lvgl
# lv_drv_conf.h
CFLAGS += -I$(PROJECT_PATH)/lib/lv_drivers
##################################### 编译和链接参数 #####################################
CFLAGS ?= -O3 -g0 -Wall -Wshadow -Wundef -Wmissing-prototypes -Wno-discarded-qualifiers -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 \
-Wshift-negative-value -Wstack-usage=2048 -Wno-unused-value
LDFLAGS ?= -lm
##################################### 收集需要编译的源文件 #####################################
CSRCS += $(PROJECT_PATH)/application/main.c
CSRCS += $(PROJECT_PATH)/application/mouse_cursor_icon.c
include $(PROJECT_PATH)/lib/lib.mk
##################################### 将文件名替换为.o文件 #####################################
AOBJS = $(ASRCS:.S=.o)
COBJS = $(CSRCS:.c=.o)
# CXX_SOURCES = $(foreach dir,$(CSRCS), $(wildcard $(dir)/*.c))
# CXX_OBJCTS = $(patsubst %.c, $(OBJ_DIR)/%.o, $(CSRCS))
all: default
%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@
#@echo "CC $<"
default: $(COBJS)
$(CC) -o $(PROJECT_NAME) $(COBJS) $(AOBJS) $(LDFLAGS)
clean:
rm -f $(PROJECT_NAME) $(COBJS) $(AOBJS)
注意: 到此工程文件已经创建好了,接下来只需要解决我们工程放置文件路径导致的问题即可,目录结构如下图所示:
修改 lib/lv_demos/lv_demos.mk 文件内容如下:
CSRCS += $(shell find -L $(LVGL_DIR)/lv_demos -name "*.c")
修改 lib/lv_examples/lv_examples.mk 文件,内容如下:
CSRCS += $(shell find -L $(LVGL_DIR)/lv_examples -name \*.c)
修改 lib/lvgl/lvgl.mk 。
启动相应的功 。
在编译的过程中会有 lvgl.h 头文件的引用错误。如下所示:
#include "../../../lvgl.h"
这是因为我们移动路径导致的,所以只需要将所以文件引用改为 #include "lvgl.h" 即可 。
注意: 到此我们自己在 Linux 环境下创建的 LVGL 工程就已经完成了,这里自己创建 lvgl 的目的主要是方便版本的选择,可以根据自己的需要选择相应的 LVGL 版本.
上面的工程中会发现编译生成的.o文件和.c文件是在同一路径下的,那么在实际开发中有不方便之处,所以将.o文件指定到build文件下,操作比较简单,只需要将 Makefile 文件进行更改即可,如下所示:
Makefile 文件 。
#
# Makefile
# 编译的.o文件和.c文件在同一路径下
#
$(info "start...")
# 可执行文件名
PROJECT_NAME = lvgl_app
##################################### 项目路径 #####################################
PROJECT_PATH ?= ${shell pwd}
OBJ_DIR := $(PROJECT_PATH)/build
##################################### 设置编译器,默认使用GCC #####################################
CC = arm-linux-gnueabihf-gcc
CC ?= gcc
##################################### 所需头文件的路径 #####################################
# lv_conf.h
CFLAGS += -I$(PROJECT_PATH)/lib/lvgl
# lv_drv_conf.h
CFLAGS += -I$(PROJECT_PATH)/lib/lv_drivers
##################################### 编译和链接参数 #####################################
CFLAGS ?= -O3 -g0 -Wall -Wshadow -Wundef -Wmissing-prototypes -Wno-discarded-qualifiers -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 \
-Wshift-negative-value -Wstack-usage=2048 -Wno-unused-value
LDFLAGS ?= -lm
##################################### 收集需要编译的源文件 #####################################
CSRCS += $(PROJECT_PATH)/application/main.c
CSRCS += $(PROJECT_PATH)/application/mouse_cursor_icon.c
include $(PROJECT_PATH)/lib/lib.mk
##################################### 将文件名替换为.o文件 #####################################
CXX_OBJCTS = $(patsubst %.c, $(OBJ_DIR)/%.o, $(notdir $(CSRCS)))
SOURSE_DIR = $(dir $(CSRCS))
vpath %.c $(SOURSE_DIR)
$(OBJ_DIR)/%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@
#@echo "CC $<"
all: $(CXX_OBJCTS)
@$(CC) -o $(PROJECT_NAME) $(CXX_OBJCTS) $(LDFLAGS)
clean:
@rm -f $(PROJECT_NAME) $(CXX_OBJCTS)
笔记到此结束,有写得不好的地方望各位大佬指出 。
最后此篇关于Linux环境中使用LVGL的文章就讲到这里了,如果你想了解更多关于Linux环境中使用LVGL的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!