跳到主要内容

LVGL-v9.2移植

本章节将讲解如何移植 LVGL-v9.2 版本官方 demo 到 T113i-Industrial 开发板。

移植前准备

进行移植前,请做好以下准备。

硬件准备

  1. 开发板:T113i-Industrial 购买链接
  2. 屏幕:MIPI屏(480*800) 购买链接
  3. 线:typeC线 X2
  4. 电源:12v电源适配器

软件准备

  1. 镜像(支持触摸和显示):t113_i_linux_evb1_auto_uart0.img
  2. github仓库:lvgl/lv_port_linux: LVGL configured to work with a standard Linux framebuffer
  3. 全志线刷工具:AllwinnertechPhoeniSuit
  4. 全志USB烧录驱动:AllwinnerUSBFlashDeviceDriver

硬件接线指南

想要实现显示 LVGL demo,首先要连接好屏幕,下面是连接屏幕的指南图:

image-20240829114352122

排线的蓝色面朝上,插入开发板的mipi接口。

编译LVGL例程

搭建开发环境

编译示例程序,要用到Tina5-SDK里面的交叉编译工具,所以需要先在ubuntu上搭建好开发环境。

如果不清楚如何搭建开发环境,参考 开发环境搭建

获取资源

进入ubuntu(已搭建好相应开发环境),新建终端,获取 LVGL Framebuffer Demo(一个示例项目,展示了如何在Linux图形栈之上使用LVGL。),执行以下指令:

git clone https://github.com/lvgl/lv_port_linux.git
cd lv_port_linux/
git submodule update --init --recursive

记录信息如下:

ubuntu@ubuntu1804:~/T113-i/lvgl_demo$ git clone https://github.com/lvgl/lv_port_linux.git
Cloning into 'lv_port_linux'...
remote: Enumerating objects: 206, done.
remote: Counting objects: 100% (103/103), done.
remote: Compressing objects: 100% (63/63), done.
remote: Total 206 (delta 62), reused 55 (delta 40), pack-reused 103 (from 1)
Receiving objects: 100% (206/206), 967.99 KiB | 932.00 KiB/s, done.
Resolving deltas: 100% (96/96), done.
ubuntu@ubuntu1804:~/T113-i/lvgl_demo$ ls
lv_port_linux
ubuntu@ubuntu1804:~/T113-i/lvgl_demo$ cd lv_port_linux/
ubuntu@ubuntu1804:~/T113-i/lvgl_demo/lv_port_linux$ git submodule update --init --recursive
Submodule 'lvgl' (https://github.com/littlevgl/lvgl.git) registered for path 'lvgl'
Cloning into '/home/ubuntu/T113-i/lvgl_demo/lv_port_linux/lvgl'...
Submodule path 'lvgl': checked out '72dfc1d75198a126dd495483d9cbc5b27c6c882b'

查看目录结构:

ubuntu@ubuntu1804:~/T113-i/lvgl_demo/lv_port_linux$ tree -L 2
.
├── CMakeLists.txt
├── LICENSE
├── lv_conf.defaults
├── lv_conf.h
├── lvgl
│   ├── CMakeLists.txt
│   ├── CMakePresets.json
│   ├── component.mk
│   ├── demos
│   ├── docs
│   ├── env_support
│   ├── examples
│   ├── idf_component.yml
│   ├── Kconfig
│   ├── library.json
│   ├── library.properties
│   ├── LICENCE.txt
│   ├── lv_conf_template.h
│   ├── lvgl.h
│   ├── lvgl.mk
│   ├── lvgl.pc.in
│   ├── lv_version.h
│   ├── lv_version.h.in
│   ├── README.md
│   ├── SConscript
│   ├── scripts
│   ├── src
│   ├── tests
│   └── zephyr
├── main.c
├── Makefile
├── manifest.json
├── mouse_cursor_icon.c
└── README.md

9 directories, 25 files

交叉编译准备

示例项目准备好之后,接下来就是准备编译了。

这个示例项目是运行在开发板上,并不是运行在Ubuntu上,需要在Ubuntu上,根据前面搭建好的开发环境,在里面找到交叉编译工具链的位置,编译出可以在开发板上运行的可执行程序。

Tina5-SDK源码根目录上,查看文件.buildconfig

image-20240829143537975

可以看到交叉编译工具链的位置(根据实际位置为主):

/home/ubuntu/T113-i/tina5sdk-bsp/out/toolchain/gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabi/bin

ls查看交叉编译工具如下:

image-20240829143941574

示例项目使用 Cmake 来生成的 Makefile,再进行编译,这里不使用示例项目自带的 Makefile 文件。

在示例项目文件lv_port_linux里,创建一个文件toolchain.cmake,用来指定交叉编译工具。

ubuntu@ubuntu1804:~/T113-i/lvgl_demo/lv_port_linux$ vim toolchain.cmake

根据实际的交叉编译工具链路径,写入以下内容:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(tools "/home/ubuntu/T113-i/tina5sdk-bsp/out/toolchain/gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabi")
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabi-g++)

写入完成后,在vim普通模式下,输入:wq保存退出。

修改 CMakeLists.txt 文件,注释无需使用的库,否则编译会报错。

ubuntu@ubuntu1804:~/T113-i/lvgl_demo/lv_port_linux$ vim CMakeLists.txt

image-20240830182538605

注释完成后,在vim普通模式下,输入:wq保存退出。

编译例程

为了方便执行编译操作,在示例项目文件lv_port_linux里,编写一个脚本build.sh

ubuntu@ubuntu1804:~/T113-i/lvgl_demo/lv_port_linux$ vim build.sh

写入以下内容:

rm -rf build
mkdir -p build
cd build/
cmake -DCMAKE_TOOLCHAIN_FILE="../toolchain.cmake" ..
make -j8

写入完成后,在vim普通模式下,输入:wq保存退出。

为了让系统能够直接执行脚本文件,还需要给它设置执行权限,执行以下指令:

sudo chmod +x build.sh

做完以上操作,即可开始执行脚本编译:

ubuntu@ubuntu1804:~/T113-i/lvgl_demo/lv_port_linux$ ./build.sh

注意:

cmake 版本要大于 3.12.4,否则编译会报错,本教程使用的 cmake 版本是3.28.3

编译如下:

image-20240830195030125

运行示例程序

编译完成后,可执行程序保存在bin目录下。

image-20240830195211708

进入 bin 目录里,查看可执行程序main文件信息:

ubuntu@ubuntu1804:~/T113-i/lvgl_demo/lv_port_linux/bin$ file main 
main: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=46eb92718f7205586815c7f4d53495fd13b93be5, with debug_info, not stripped

从以上信息可以看到,main 是一个为 ARM 架构编译的 32 位 ELF(Executable and Linkable Format)可执行文件,可以在开发板上运行。

adb上传程序

在Ubuntu上,使用 adb 工具把可执行程序main上传到开发板的/mnt/UDISK/底下,

执行以下指令:

adb push main /mnt/UDISK/

image-20240830200230538

登录开发板终端

如果不清楚如何登录开发板终端,请参考 启动开发板 | 东山Π (100ask.org)

运行程序

进入开发板终端之后,执行以下指令,运行程序:

/mnt/UDISK/main

image-20240831133627374

支持触摸

示例项目提供了framebuffer显示,也提供触摸输入,下面将讲解如何支持触摸(前提:开发板已适配屏幕的触摸功能)。

首先需要确定哪个设备节点是支持触摸的,在开发板上,执行以下指令:

cat /proc/bus/input/devices

可以看到,支持触摸的设备节点是 /dev/input/evnet3

image-20240830202346988

如果不知道哪个是触摸的设备节点,可以使用 hexdump 或者 cat工具一个一个输入设备节点进行测试,点击触摸屏幕,有数据的往往就是了,如下:

# hexdump /dev/input/event3
0000000 5896 0000 f76d 0003 0003 0039 0006 0000
0000010 5896 0000 f76d 0003 0003 003a 007f 0000
0000020 5896 0000 f76d 0003 0003 0030 0004 0000
0000030 5896 0000 f76d 0003 0003 0035 0143 0000
0000040 5896 0000 f76d 0003 0003 0036 0246 0000
0000050 5896 0000 f76d 0003 0001 014a 0001 0000
0000060 5896 0000 f76d 0003 0000 0000 0000 0000
0000070 5896 0000 1ff9 0004 0003 0039 ffff ffff
0000080 5896 0000 1ff9 0004 0001 014a 0000 0000
0000090 5896 0000 1ff9 0004 0000 0000 0000 0000

使用 cat 工具测试,则是返回一堆乱码,这里就不测试了。

经过测试,可以确定支持触摸的设备节点是 /dev/input/event3,在Ubuntu上,进入示例项目lv_port_linux目录底下,修改main.c

添加如下代码:

lv_indev_t * indev = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event3")

image-20240830203224539

添加完成后,在vim的普通模式下,执行 :wq退出保存。

还不能马上编译,还需要修改示例项目lv_port_linux目录底下的配置文件 lv_conf.h

vim lv_conf.h

找到LV_USE_EVDEV,把 0 修改成 1,表示启用对 Linux 输入设备(通过 evdev 接口)支持的宏定义。

image-20240830203550919

修改完成后,在vim的普通模式下,执行 :wq退出保存。

根据之前的步骤,执行编译程序、上传程序和运行程序等操作,这样就屏幕可以支持触摸了。