2. LVGL

2.1. 什么是LVGL

LVGL由匈牙利开发者 Gábor Kiss - Vámosi 于2009年开始编写,2016年重写并发布在GitHub上,目前已成为最受欢迎的嵌入式图形库之一。它广泛应用于智能家居控制面板、医疗设备界面、汽车仪表盘等各种嵌入式设备的界面设计。

LVGL具有以下特性:

  • 多种用户自定义控件:提供超过 30 种丰富的用户自定义控件,如按钮、滑条、文本框、键盘等,能满足各种用户界面的设计需求。

  • 良好的屏幕适配性:支持各种分辨率的屏幕,无论是小型单色显示器还是全高清显示器,都能很好地适配。

  • 多输入设备支持:支持触摸屏、鼠标、键盘、编码器等多种输入设备,可增强用户交互体验。

  • 丰富的绘图元素:提供抗锯齿、多边形、阴影、线、弧等多种绘图元素,使界面更加美观。

  • 多语言和多字体文本支持:采用 UTF - 8 编码,支持多语言、多字体的文本,能满足全球不同用户的需求。

  • 多种图片类型支持:支持各种图片类型,可从 Flash 和 SD 卡中读取图片显示,还提供在线图片取模工具。

  • 硬件要求低:16、32、64位微控制器或微处理器,时钟大于16MHz,Flash/ROM大于64KB,RAM大于16KB。

2.2. 获取LVGL源码

野火获取LVGL官方v9.2版本的源码进行适配,对应源码仓库如下:

注意

本教程以野火LVGL源码为样本,如果需要移植官方源码请自行百度研究。

获取野火LVGL源码:

1
git clone https://github.com/LubanCat/lv_port_linux.git

2.3. 编译LVGL源码

2.3.1. 获取交叉编译工具链

LubanCat-sg200x的RISCV核使用的交叉编译工具链为riscv64-unknown-linux-gnu-gcc,版本10.2.0,访问资料网盘/7-SDK源码压缩包及虚拟机获取虚拟机镜像, 下载host-tools.tar.gz交叉编译工具链压缩包。

下载完成后传到虚拟机或服务器,进行解压:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#解压编译工具链到工作目录
tar xvf host-tools.tar.gz

#进交叉编译链目录
cd host-tools/gcc/riscv64-linux-x86_64/bin

#查看编译工具链版本
./riscv64-unknown-linux-gnu-gcc -v
#信息输出如下
Using built-in specs.
COLLECT_GCC=./riscv64-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/home/guest/sg200x/sophon-image-build/host-tools/gcc/riscv64-linux-x86_64/bin/../libexec/gcc/riscv64-unknown-linux-gnu/10.2.0/lto-wrapper
Target: riscv64-unknown-linux-gnu
Configured with: /mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/./source/riscv/riscv-gcc/configure --target=riscv64-unknown-linux-gnu --with-gmp=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-mpfr=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-mpc=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-libexpat-prefix=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-libmpfr-prefix=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-pkgversion='Xuantie-900 linux-5.10.4 glibc gcc Toolchain V2.6.1 B-20220906' CXXFLAGS='-g -O2 -DTHEAD_VERSION_NUMBER=2.6.1 ' --prefix=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1 --with-sysroot=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/sysroot --with-system-zlib --enable-shared --enable-tls --enable-languages=c,c++,fortran --disable-libmudflap --disable-libssp --disable-libquadmath --enable-libsanitizer --disable-nls --disable-bootstrap --src=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/./source/riscv/riscv-gcc --enable-multilib --with-abi=lp64d --with-arch=rv64gcxthead 'CFLAGS_FOR_TARGET=-O2   -mcmodel=medany' 'CXXFLAGS_FOR_TARGET=-O2   -mcmodel=medany'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (Xuantie-900 linux-5.10.4 glibc gcc Toolchain V2.6.1 B-20220906)

从输出信息可见,交叉编译工具链适用于riscv64平台,版本为10.2.0。

如果需要导出环境变量,可进行以下操作:

1
2
3
4
5
#导出环境变量,需要根据实际指定编译工具链的绝对路径
export PATH=/home/guest/sg200x/sophon-image-build/host-tools/gcc/riscv64-linux-x86_64/bin/:$PATH

#查看编译工具链,如果COLLECT_LTO_WRAPPER变量为指定的路径,即配置成功
riscv64-unknown-linux-gnu-gcc -v

以上配置为临时导出环境变量,打开其他终端或者重启都需要重新导出环境变量,如需永久保存需要将导出环境变量的命令写入~/.bashrc文件末尾,并执行source ~/.bashrc 重新加载配置。

2.3.2. 修改交叉编译工具链路径

LVGL源码(lv_port_linux)根目录下的CMakeLists.txt是CMake的配置文件,借助CMakeLists.txt文件,能够定义项目的构建规则、源文件、头文件路径、编译选项、链接库等内容。

根据交叉编译工具链实际路径修改CMakeLists.txt内容:

1
2
3
# 这里指定的路径必须是绝对路径
set(CMAKE_C_COMPILER /home/guest/sg200x/sophon-image-build/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-gcc)
set(CMAKE_CXX_COMPILER /home/guest/sg200x/sophon-image-build/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-g++)

2.3.3. 编译源码

确保cmake版本在3.12.4以上,之后运行如下命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#进入LVGL源码目录
cd lv_port_linux

#清除编译输出
make clean

#创建构建目录并进行编译
mkdir build
cd build
cmake ..
make -j16

编译成功后,在lv_port_linux/bin目录下生成一个main的可执行程序,该程序就是可在板卡运行的程序。

../../_images/lvgl_0.jpg

2.4. 板卡运行LVGL程序

将编译生成的main程序传到板卡,然后先初始化屏幕。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#5.5寸mipi屏幕初始化
sudo /mnt/system/usr/bin/sample_panel --panel=HX8399_1080P

#7寸mipi屏幕初始化
sudo /mnt/system/usr/bin/sample_panel --panel=EK79007

#10.1寸mipi屏幕初始化
sudo /mnt/system/usr/bin/sample_panel --panel=ILI9881C

#加载fb驱动
sudo insmod /mnt/system/ko/cvi_fb.ko

然后创建run_lvgl.sh脚本,配置环境变量并运行main程序,run_lvgl.sh脚本内容如下:

1
2
3
4
5
#!/bin/bash

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib64v0p7_xthead/lp64d

/home/cat/main

脚本添加执行权限并运行:

1
2
3
sudo chmod 777 run_lvgl.sh

./run_lvgl.sh

运行效果如下:

../../_images/lvgl_1.jpg

2.5. 运行自己的程序

2.5.1. 运行野火测试程序

野火在LVGL官方源码基础上添加了gui-guider目录,并在lv_port_linux/CMakeLists.txt中进行指定。gui-guider是使用NXP的GUI-Guider工具生成的。

在lv_port_linux/main.c中引用了gui-guider中相关头文件以及函数接口。

截取main.c内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#include "custom.h"
#include "lv_conf.h"
#include "generated/gui_guider.h"
#include "generated/events_init.h"

.........

int main(void)
{
    lv_init();

    /*Linux display device init*/
    lv_linux_disp_init();

    // 这行默认是没有的,因此我们无法使用input驱动,也就无法点击触摸屏
    lv_indev_t * indev = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event1");

    /*Create a Demo*/
    lv_demo_widgets();
    //lv_demo_widgets_start_slideshow();

    // setup_ui(&guider_ui);
    // events_init(&guider_ui);

    /*Handle LVGL tasks*/
    while(1) {
        lv_timer_handler();
        usleep(5000);
    }

    return 0;
}

修改int main(void)函数,将lv_demo_widgets官方测试程序注释,打开野火测试程序,修改如下:

1
2
3
4
5
6
/*Create a Demo*/
//lv_demo_widgets();
//lv_demo_widgets_start_slideshow();

setup_ui(&guider_ui);
events_init(&guider_ui);

修改完成后重新编译源码,将main可执行程序传到板卡运行,效果如下:

../../_images/lvgl_2.jpg

2.5.2. 手搓自己的LVGL应用

下面是一些手搓的资料:

2.5.3. 可视化工具创建LVGL应用

可视化工具有很多,这里介绍一个使用起来比较方便的工具 Gui Guider

目前该工具在持续更新中,包含比较新的lvgl v9的界面编辑

下面以一个例子教大家如何使用 Gui Guider 创建自己的应用,以LVGL v9为例

2.5.3.1. 下载软件

下载地址: https://www.nxp.com/design/design-center/software/development-software/gui-guider:GUI-GUIDER

进入页面后,点击 Download 按钮,会跳转到下载目录,如下图所示

未找到图片
  • 需要注意的是本教程的 lvgl 版本是和 GUI Guider v1.9.0 相配合的, 如果使用新版本需要注意 lvgl 版本是否支持

  • 这里小编使用的是 windows版本,点击红框内容选择 GUI Guider v1.9.0 Installer for Windows 下载

  • 下载需要账户验证,可以创建账号或者登录账号获取下载权限

或者访问资料网盘/6-开发软件,下载Gui-Guider-Setup-1.9.0-GA-WIN.exe

注意

Gui-Guider是需要NXP账号的,请自行访问NXP官方网站进行注册。

2.5.3.2. 安装软件

该部分跳过,这里就不过多描述

2.5.3.3. 打开软件

打开软件后,会提示账号登录,需要把账号登录上才能正常使用, 登录完账号可以看到下面内容

未找到图片

2.5.3.4. 创建应用

  • 点击红框创建一个新项目

未找到图片
  • 选择 v9.2.1 然后点击 next

未找到图片
  • 点击 simulator ,然后选择 simulator 页面,然后点击 next

未找到图片
  • 然后就会进入创建项目内容的界面

  • 需要注意的是例子里面的程序有很多因为版本问题没办法直接跑通,最好是自己建应用

  • 这里我选择空白应用进行选择,然后点击 next

未找到图片
  • 然后会进入工程的配置信息,配置好程序后,点击 creat

未找到图片
  • 创建后会自动打开工程,如下图所示

未找到图片
  • 然后就可以在 simulator 页面进行操作了,这里小编就创建一个简单的应用,如下图所示

未找到图片
未找到图片
未找到图片

2.5.3.5. 导出代码

应用能正常操作了,可以导出代码了

点击 project -> Export code -> RT-thread ,然后选择路径,点击 打开

未找到图片
  • 导出成功后,会自动打开导出的文件夹,如下图所示,会有两个文件夹,分别是 customgenerated

未找到图片
  • 然后可以把LVGL源码中的 lv_port_linux/gui-guider 下的 customgenerated 文件夹替换成导出的文件夹

然后重新编译程序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#进入LVGL源码目录
cd lv_port_linux

#清除编译输出
make clean

#创建构建目录并进行编译
mkdir build
cd build
cmake ..
make -j16

把生成的lv_port_linux/bin/main程序放到板卡上运行,效果如下:

未找到图片