LVGL (Light and Versatile Graphics Library)

Introduction

LVGL is a graphics library that uses a minimum amount of resources and enables the creation of highly sophisticated user interfaces. LVGL requires only a simple framebuffer device to work, making it ideal for running on a karo-minimal Yocto distro. LVGL is a free and open-source graphics library that provides everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects, and a low memory footprint.

Precautions

Warning

The following code examples are for the QSMP-1351 module. Please note that the examples provided are specific to the QSMP-1351 module and may require adaptation for use with other modules.

Building the OS image

The LVGL graphics library operates on a straightforward framebuffer device. A minimal image created with the Karo software is all that is needed to provide this.

DISTRO=karo-minimal MACHINE=qsmp-1351 source karo-setup-release.sh -b build-qsmp-1351-karo-minimal
bitbake karo-image-minimal

Once you’ve built the image, just program it into the flash memory, as shown in this article: Fast Flashing STM32MP1 Boards

Prior to launching the Linux operating system, it is necessary to configure certain environmental variables within the bootloader in order to define the baseboard and video timing parameters.

setenv baseboard qsbase1
setenv videomode ET0700
saveenv

Building the SDK

In order to cross-compile an LVGL application on a host machine, it is necessary to have a software development kit (SDK) for the target platform. To build your SDK, just use this Yocto command.

bitbake karo-image-minimal -c populate_sdk

You will find the installation script for your SDK here:

<path-to-your-build-directory>/tmp/deploy/sdk/

Before you start cross-compiling your LVGL application, you’ll need to source the right SDK. For example:

. /opt/st/sdk/environment-setup-cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi

Downloading and Cross-compiling the LVGL library and sample apps

The first thing you need to do is create a project directory. Once you’re in that directory, just follow these steps to download the LVGL source code for libraries and sample apps:

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

The sources are now essentially prepared for cross-compiling. Prior to commencing, it is recommended that certain modifications be made for the purpose of optimizing the code. It should be noted that these optimizations are not a prerequisite for the code to be executed; they are solely intended to enhance its performance.

in the file lv_conf.h please change:

#define LV_USE_ASSERT_STYLE         0
#define LV_USE_ASSERT_MEM_INTEGRITY 0
#define LV_USE_ASSERT_OBJ           0

To use the touch screen, please also change the following item in lc_conf.h:

#define LV_USE_EVDEV    1

The CMake tool chain is now employed for the build of the LVGL libraries and application:

cmake -B build -S .
make -C build -j

It should be noted that the standard toolchain produces a binary file with statically linked libraries. The resulting binary can be found in the bin directory.

Mount an NFS Share

Network File System (NFS) is a distributed file system protocol that allows you to share remote directories over a network. With NFS, you can mount remote directories on your system and work with the remote files as if they were local files. On your target device, you can use the mount command to mount a shared NFS directory on a particular mount point in the local directory tree.

This functionality allows the user to start the LVGL application build on the Linux host system directly on the target system, eliminating the need for file copying.

If you’re exporting directories via NFS, they all need to be subordinate to a common root directory that serves as a pseudo file system.

On the host system create NFS root mount point in the file system (if not already done), used for nfs export. In my example it is:

sudo mkdir -p /nfsexport/lvgl

Next, bind your project directory to this mount point. To get this done automatically every time your system starts up, just add an entry to your host’s fstab table.

The entry in /etc/fstab, in my case:

 # <file system>                  <mount point>        <type>  <options>       <dump>  <pass>
/home/<my-name>/projects/lvgl     /nfsexport/lvgl      none    bind              0       0

Once you have made the changes to the file, just run the command

sudo mount -a

to apply them immediately.

The file /etc/exports serves as the primary configuration file for the Network File System (NFS) server. It defines the authorized access permissions for specific directories, allowing or denying access to particular computers. In this example, all computers within the local network are granted access to the LVGL project folder.

/nfsexport/lvgl 192.168.0.0/23(rw,sync,no_subtree_check)

Once modifications have been made to the /etc/exports file, the following command should be executed in order to inform the NFS server of the changes:

sudo exportfs -a

NFS-Mount your host’s project folder on your target device

In order to create a writable root file system (rootfs) on the QSMP-1351 target device, it is first necessary to use the rw-command. The next step is to generate a mount point for the Network File System (NFS) folder, which is then mounted:

rw
mkdir /mnt/lvgl
mount -t nfs <your-host-IP>:/nfsexport/lvgl /mnt/lvgl

Starting the cross-compiled LVGL application on your target device

Once an NFS mount of the LVGL project directory has been established, the new build binary can be started directly on the target device with minimal effort.

First, you’ll want to set up an environment variable to specify the touch device:

export LV_LINUX_EVDEV_POINTER_DEVICE="/dev/input/touchscreen0"

Switch off the cursor on the terminal that’s running on the frame buffer device.

setterm -cursor off > /dev/tty0

Finally, let’s get started with the LVGL application.

/mnt/lvgl/lv_port_linux/bin/lvglsim