之前有记录过在 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

  1. 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 命令更新一下即可。

  2. 工程目录

    拉取完成后,工程目录如下所示:

  3. 编译工程

    直接使用 make 命令编译即可,完成后如下图所示:会直接生成可执行文件,如下图所示:

    注意: 发现可执行文件后,基本就完成了,直接运行即可,./demo ,毫无疑问基本会运行失败,结果如下图所示:

  4. 修改显示驱动

    这里的显示驱动都是使用的 Framebuffer 缓冲区,我之间有个简单的笔记使用,不了解的小伙伴,可以看我之前的笔记,Linux Framebuffer 实验,知道自己的缓冲区设备后,就可以直接在文件 lv_drv_conf.h 中进行修改,不过多数情况下都是 /dev/fb0 可以不用修改,如下图所示:

  5. 修改鼠标或触摸驱动

    在修改鼠标或触摸驱动时,需要借助 evtest 工具,找到自己设备的输入事件。

    • 安装 evtset 工具

      sudo apt-get install evtest
    • 使用命令 sudo evtest 找到对应的事件编号,如下图所示:

    找到鼠标事件后,直接在 lv_drv_conf.h 文件中,更改对应的事件编号即可,如下图所示:

  6. 运行测试

    完成驱动修改后,重新编译测试,因为使用的是 Framebuffer 缓冲区,所以在 ubuntu 缓冲区中使用是,需要关闭图形显示后,才是正常使用 Framebuffer ,命令如下

    # 关闭图形显示
    systemctl set-default multi-user.target
    reboot # 打开图形显示
    systemctl set-default graphical.target
    reboot

    关闭图形显示后,测试结果如下图所示:

三、方式二

上面我们已经完成了,在 ubuntu 中测试 LVGL 操作还是比较简单的,现在我们开始尝试手动创建工程,并将编译后生成的.o文件放到指定目录下,然后更改编译工具,使其在arm开发板中进行使用。

注意: 在创建过程中,有什么问题可以直接参考上面的工程,可以解决我们过程中遇到的问题

  1. 下载 LVGL

  2. 创建工程目录

    这里我就不详细说明了,直接上图,只要文件目录如图所示一样即可,路径图下图所示:

  3. 将 lvgl 移动到 lib 文件下,并删除多余的文件,如下图所示:



    注意:其中的 lv_conf.h 文件是直接将 lv_conf_template.h 拷贝后进行重命名的,完成后将文件中的 #if 0 改为 #if 1

  4. 将 lvgl 目录下的 demos 文件拷贝到 lib 文件下,如下图所示:



    注意:这里为了 demos 使用中减少问题,我直接拷贝了 lvgl 文件下的 demos 并重命名为 lv_demos

  5. 将 lv_drivers 拷贝到 lib 文件下,并删除多余的文件,如下图所示:



    注意:其中 lv_drv_conf.h 文件是拷贝 lv_drv_conf_template.h 文件重命名后得到的,完成后将文件中的 #if 0 改为 #if 1

  6. 将 lvgl 目录下的 examples 文件拷贝到 lib 文件下,如下图所示:

  7. 在 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;
    }
  8. 拷贝鼠标文件 mouse_cursor_icon.c

    将方式一中获取到的鼠标文件拷贝到 application 文件下

  9. 在 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
  10. 在主目录下创建 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)

注意: 到此工程文件已经创建好了,接下来只需要解决我们工程放置文件路径导致的问题即可,目录结构如下图所示:

  1. 修改 lib/lv_demos/lv_demos.mk 文件内容如下:

    CSRCS += $(shell find -L $(LVGL_DIR)/lv_demos -name "*.c")
  2. 修改 lib/lv_examples/lv_examples.mk 文件,内容如下:

    CSRCS += $(shell find -L $(LVGL_DIR)/lv_examples -name \*.c)
  3. 修改 lib/lvgl/lvgl.mk

  4. 启动相应的功

    • USE_FBDEV:在文件 lv_drv_conf.h 中
    • USE_EVDEV:在文件 lv_drv_conf.h 中
    • LV_USE_DEMO_WIDGETS:在文件 lv_conf.h,主要作用是启动相应的案例
  5. 在编译的过程中会有 lvgl.h 头文件的引用错误。如下所示:

    #include "../../../lvgl.h"

    这是因为我们移动路径导致的,所以只需要将所以文件引用改为 #include "lvgl.h" 即可

注意:到此我们自己在 Linux 环境下创建的 LVGL 工程就已经完成了,这里自己创建 lvgl 的目的主要是方便版本的选择,可以根据自己的需要选择相应的 LVGL 版本。

四、指定 .o 文件的存放路径

上面的工程中会发现编译生成的.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的更多相关文章

  1. Linux环境中Openfire安装指南

    Linux环境中Openfire安装指南 安装环境: 安装软件:Openfire 4_1_0 http://download.igniterealtime.org/openfire/openfire_ ...

  2. 理解 Linux 网络栈(2):非虚拟化Linux 环境中的 Segmentation Offloading 技术

    本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...

  3. [软件测试]Linux环境中简单清爽的Google Test (GTest)测试环境搭建(初级使用)

    本文将介绍单元测试工具google test(GTEST)在linux操作系统中测试环境的搭建方法.本文属于google test使用的基础教程.在linux中使用google test之前,需要对如 ...

  4. linux环境中通过/dev/urandom设备产生随机密码

    需求说明: 今天在调试SVN的时候,需要创建用户的随机密码,想了下,在linux环境中是否能够生成呢,就搜索了下, 然后结合看到的帖子,分析一个可以生成密码的命令,在此记录下. 操作过程: 1.通过/ ...

  5. linux环境中,多个命令之间,通过&& ||执行,命令之间执行的逻辑是什么?

    需求描述: 最近在写一个脚本的时候,要判断一个文件是否存在,有怎么样,没有就创建,这个时候 看到了一个test 结合 || 或者 &&的写法,就查看了下资料记录下是怎么个玩法. 操作过 ...

  6. Linux环境中Qt程序的手工发布

    Linux环境中Qt程序的手工发布

  7. linux环境中通过useradd命令,创建用户的时候指定用户的base-dir

    需求说明: 今天一个同事,问了一个这样的问题,在linux环境中,创建用户的时候,默认的是在/home目录下创建一个与用户名相同的家目录, 如何能够将这个/home更换成一个其他的,比如/opt/ap ...

  8. linux环境中安装ftp服务

    需求说明: 今天项目中有一个新的需求,需要在linux环境中搭建一个ftp服务,在此记录下. 操作过程: 1.通过yum的方式安装ftp服务对应的软件包 [root@testvm01 ~]# yum ...

  9. linux环境中,查看域名的DNS信息?

    需求说明: 今天在linux主机上,要查询一个域名是在哪个DNS上进行解析的,这个域名下面还有哪些的地址 操作过程: 1.linux环境中通过nslookup命令来进行查看 [deployer@CBS ...

  10. linux环境中,两个不同网段的机器互通

    linux环境中,两个不同网段的机器互通   人评论3690人阅读2019-11-18 14:50:21   环境如下:   host1 单网卡 eth0 172.24.100.15/16   hos ...

随机推荐

  1. PAT甲级英语单词整理

    proper 正确 合适 vertex(vertices)顶点 respectively 个别 分别 indices 指标 索引 shipping 运输 incompatible 不相容 oxidiz ...

  2. Docker 部署 Kibana

    Docker 部署 Kibana 本篇主要介绍 使用 Docker 部署 kibana 用于操作 Elasticsearch 使用. 1. 前置准备 1.1 Elasticsearch 准备 可以先准 ...

  3. Linux-->文件目录作用查询

    Linux的目录结构 在Linux中他的根目录都是决定好的无法改名,并且每一个目录他的作用都是决定好的 在Linux中一切都是文件!,Linux会把所有的硬件都映射成文件 / 代表根目录 /bin / ...

  4. iptables基本使用举例

    一.链的基本操作 1.清除所有的规则. 1)清除预设表filter中所有规则链中的规则. # iptables -F 2)清除预设表filter中使用者自定链中的规则. #iptables -X #i ...

  5. vue路由守卫用于登录验证权限拦截

    vue路由守卫用于登录验证权限拦截 vue路由守卫 - 全局(router.beforeEach((to, from, next) =>来判断登录和路由跳转状态) 主要方法: to:进入到哪个路 ...

  6. 简单将Springboot项目部署到linux服务器上

    1.使用springboot的jar包方式 直接使用maven工具按照步骤点击就可以直接打包 2.到target目录下找到 jar包 3.将jar包放到linux的任意文件夹下(此项目是之前的kafk ...

  7. 齐博x1标签之无刷新显示更多

    示范代码如下: <div class="ListMoreInfos"> {qb:tag name="news_list_page_listdata02&quo ...

  8. python3使用mutagen进行音频元数据处理

    python版本:python 3.9   mutagen版本:1.46.0 mutagen是一个处理音频元数据的python模块,支持多种音频格式,是一个纯粹的python库,仅依赖python标准 ...

  9. Spring事务传播行为实战

    一.什么是事务传播行为? 事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何运行. 例如:methodA方法调用methodB方 ...

  10. stm32h750移植lvgl

    之前没做过ui,只用过lcd画几条线写点字,如果按键.菜单什么的全用线画也太麻烦了,所以需要一个ui库. 听说lvgl用的人很多,就打算裸机移植一下用用.本文移植的lvgl版本是lvgl6.2,也移植 ...