Last edited 2 weeks ago

How to build LVGL applications using STM32CubeIDE

Applicable for STM32MP13x lines  STM32MP15x lines


This article gives information about how to easily develop a LVGL application on STM32MP1 series using STM32CubeIDE with OpenSTLinux distribution, in Linux context. LVGL library release used for this article is the release 8.1. You can develop and design your application with squareline tool (see reference "LVGL learning course") and then adapt the project to your board.


1. Architecture overview[edit | edit source]

The following diagram summarizes all the configurations of the LVGL library. This article details each of the possible configurations and proposes demonstration usage examples with STM32CubeIDE.

Lvgl configurations.png

1.1. Components presentation[edit | edit source]

1.1.1. LVGL[edit | edit source]

https://lvgl.io/

LVGL (Light and Versatile Graphics Library) is an open-source embedded GUI library that is written in C (with C++ compatibility) and is released under the MIT license. It is optimized for deployment on microcontrollers/microprocessors and bare-metal (no OS) devices. This article explains how to develop LVGL applications for the STM32MP1 microprocessors running with OpenSTLinux Linux® distribution. LVGL release 8.1 is the version used for this article.

1.1.2. SDL2[edit | edit source]

https://www.libsdl.org/index.php

SDL or Simple Direct Media Layer is a cross-platform development library designed to provide low-level access to audio, keyboard, mouse, joystick, and graphics hardware. It allows, for example, the display of windows and images, the playback of sounds, and the management of keyboards.

SDL is written in C, works natively with C++, and there are bindings available for several other languages, including C# and Python™.

SDL 2.0 is distributed under the zlib license. This license allows the use of SDL freely in any software.

1.1.3. Wayland / Weston[edit | edit source]

https://wayland.freedesktop.org/architecture.html?_sm_au_=iVV4MHTR7sLqs9RQcLpsvK618Vf61

Wayland is a protocol that allows a composer to communicate with multiple windows. It works only with systems using KMS (Kernel-based mode-setting), a kernel feature dependent on the graphics card driver used. For this reason, a composer must be used.

A composer implementing the Wayland protocol (such as Mutter, Kwin, Enlightenment, Weston, or others) is necessary. Otherwise, Wayland alone performs no operation, and it is always an X server that would be used.

The composer is a window manager, which uses a buffer in memory to manage each window and apply visual effects to it.

Weston is the reference implementation of a graphical composer window manager for the Wayland display protocol. Its existence is justified by the need to develop Wayland without depending on the ups and downs of the development of libraries and environments. It is also justified by the need to be able to rigorously test Wayland without experiencing bugs independent of Wayland.

1.1.4. DRM-KMS[edit | edit source]

For more information about DRM-KMS, refer to the following article: DRM_KMS_overview

1.2. Different configurations[edit | edit source]

1.2.1. Weston Wayland SDL2 configuration with GPU[edit | edit source]

Lvgl conf1.png

1.2.2. DRM-KMS / SDL2 configuration with GPU[edit | edit source]

Lvgl conf2.png


1.2.3. Direct DRM-KMS configuration without GPU[edit | edit source]

Lvgl conf3.png

2. How to build LVGL project with STM32CubeIDE[edit | edit source]

2.1. Get SDK[edit | edit source]

The SDK provided with the OpenSTLinux Ecosystem release can be used.

To install SDK you can refer to STM32MPU Developer Package#Installing_the_SDK

2.2. Configure STM32CubeIDE with SDK[edit | edit source]

  • To be able to use the SDK:
    • In STM32CubeIDE, navigate to Window ==>Preferences ==>STM32Cube ==>OpenSTLinux SDK Manager
    • Browse and select the directory containing the OpenSTLinux toolchains
    • Click on "Apply an close "


SDK.png


Note that this manages the SDKPATH variable.

2.3. Get LVGL project for STM32MP1[edit | edit source]

Open a PC Linux terminal in a new folder.

  • Download the LVGL project with the following command
  • Apply modification for LVGL project for STM32MP1

lvgl_stm32mp_patch.zip [1]

  • Rename lv_port_pc_eclipse directory (for instance lv_stm32mp_lvgl)

Section 5 explains how the modifications on the LVGL project for STM32MP1 have been applied for release 8.1.

git clone --recursive https://github.com/lvgl/lv_port_pc_eclipse.git
cd lv_port_pc_eclipse/
git checkout -b WORKING origin/release/v8.1
git submodule init
git submodule update

cd ..
cp -a ./lvgl_stm32mp_patch/* ./lv_port_pc_eclipse/
mv lv_port_pc_eclipse  lv_stm32mp_lvgl

LVGL github project LVGL's GitHub

LVGL Windows.png

2.4. Import then Configure and Build CMake LVGL project for STM32MP1[edit | edit source]

  • Import your CMake project:

Click on file ==> New ==> STM32 CMake project upload your LVGL project.

Cmake project.png


Chemin.png


  • Select source directory:


Source dir.png


  • Select the toolchain for OpenSTLinuxSDK


Toolchain.png


  • Activate your LVGL STM32MP1 configuration for your board

modify CMakeLists.txt for your configuration

configuration 1

option(STM32MP_LVGL_WAYLAND_SDL2_GPU BOOLEAN ON)
option(STM32MP_LVGL_DRM_KMS_SDL2_GPU BOOLEAN OFF)
option(STM32MP_LVGL_DIRECT_DRM_KMS_NOGPU BOOLEAN OFF)


configuration 2

option(STM32MP_LVGL_WAYLAND_SDL2_GPU BOOLEAN OFF)
option(STM32MP_LVGL_DRM_KMS_SDL2_GPU BOOLEAN ON)
option(STM32MP_LVGL_DIRECT_DRM_KMS_NOGPU BOOLEAN OFF)


configuration 3

option(STM32MP_LVGL_WAYLAND_SDL2_GPU BOOLEAN OFF)
option(STM32MP_LVGL_DRM_KMS_SDL2_GPU BOOLEAN OFF)
option(STM32MP_LVGL_DIRECT_DRM_KMS_NOGPU BOOLEAN ON)


  • CMake Configure

Select project ==> right click ==> CMake Configure Delete and Reconfigure

Cmake configure 1.png



Cmake configure 2.png



Cmake configure 3.png



Cmake configure 4.png


  • Build the project with the generated Makefile

3. Run the demonstration[edit | edit source]

You must build the binary for your configuration.

  • Build the project:

Right-click on your project ==> Build project

  • You can then run the binary with STM32CubeIDE using "C/C++ Remote Application" run configuration.

it is also possible to run it manually as follows:

  • Find the binary file in your project (folder "config_default" binary name "main") .
  • Setup a terminal on the board.
minicom  -D /dev/ttyACM0
  • To get the IP address of your target, type the following commands:
ifconfig 
...
eth1      Link encap:Ethernet  HWaddr 10:E7:7A:E3:47:C8  
         inet addr:10.48.1.145  Bcast:10.48.3.255  Mask:255.255.252.0
         inet6 addr: fe80::12e7:7aff:fee3:47c8/64 Scope:Link
inet is the ip address of your target

or

ip addr
 ...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
   link/ether 10:e7:7a:e3:47:c8 brd ff:ff:ff:ff:ff:ff
   inet 10.48.1.145/22 metric 10 brd 10.48.3.255 scope global dynamic eth1


  • Copy the binary to the board using the following command:
scp <name_of_your_binary> root@<IP_address>:/usr/local/

To force binary writing onto the SD™ card:

sync

3.1. Run your binary with SDL2 configuration (configuration 1 and 2)[edit | edit source]

For using SDL, you must indicate to SDL2 library which backend to use: here wayland or kmsdrm.

  • In configuration 1: Weston Wayland SDL2 configuration with GPU

The environment variable for SDK2 videodriver must be set to Wayland. The binary must be executed with Weston permission:

su -l weston -c "SDL_VIDEODRIVER=wayland /usr/local/<name_of_your_binary >"

To kill the binary execution:

CTRL + c
  • In configuration 2: DRM-KMS / SDL2 configuration with GPU

For this configuration, you MUST stop the Weston service before running your binary (refer to How to stop and start Weston):

systemctl stop weston-graphical-session.service
export SDL_VIDEODRIVER=kmsdrm 

To run the binary:

/usr/local/<name_of_your_binary >

To kill the current project:

CTRL + c

3.2. Run your binary in direct DRM-KMS configuration (configuration 3)[edit | edit source]

To run the binary you MUST stop the Weston service before running your binary (refer to How to stop and start Weston)):

systemctl stop weston-graphical-session.service
/usr/local/<name_of_your_binary >

To kill the current project:

CTRL + c

3.3. Summary[edit | edit source]

As a summary, to run the different configurations:

  • In configuration 1: Weston Wayland SDL2 configuration with GPU
su -l weston 
export SDL_VIDEODRIVER=wayland
<path to binary>/<name_of_your_binary >
  • In configuration 2: DRM-KMS / SDL2 configuration with GPU
systemctl stop weston-graphical-session.service
export SDL_VIDEODRIVER=kmsdrm 
<path to binary>/<name_of_your_binary>
  • In configuration 3: direct DRM-KMS
systemctl stop weston-graphical-session.service
<path to binary>/<name_of_your_binary >

4. Debugging the demonstration[edit | edit source]

This section shows how to debug with STM32CubeIDE.
Create a debug configuration

Debug configuration1.png


Select STM32 Cortex-A Remote Application for debug configuration.

Debug configuration2.png


In main tab

  • Set the project name and path
  • Configure the MPU SSH Weston connection
  • Configure Remote Absolute Path


Debug configuration 3 1.png



Debug configuration 3 2.png



Debug configuration3.png




In debug tab

Set GDBdebugger from SDK path to

<...>/sysroots/x86_64-ostl_sdk-linux/usr/bin/arm-ostl-linux-gnueabi/arm-ostl-linux-gnueabi-gdb

Debug configuration5.png


Follow these wiki articles:

5. Summary of modifications on LVGL project for STM32MP1[edit | edit source]

Find below how the modifications are applied to the LVGL project. The changes are already applied when copying lvgl_stm32mp_patch to lvgl project (release 8.1) in 2.3 Get LVGL project for STM32MP1.

5.1. Modifications on LVGL project (common for all configurations)[edit | edit source]

To adapt LVGL to the STM32MP1 board, some modification are needed.
The following modifications are common to all the configurations described on this page (SDL2 configurations or direct DRM-KMS configuration).

5.1.1. Adaptation of example source code (main.c)[edit | edit source]

  • Replace the content of the main file of your project by the following script:
/**
 * @file main.c
 *
 */
/*********************
 *      INCLUDES
 *********************/
#define _DEFAULT_SOURCE /* needed for usleep() */
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>

// For SDL2 usage
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
#include <SDL2/SDL.h>
#include "lvgl/lvgl.h"
#include "lvgl/examples/lv_examples.h"
#include "lv_demos/lv_demo.h"
#include "lv_drivers/sdl/sdl.h"

// For USE DRM usage
#include "lv_drivers/display/drm.h"
#include "lv_drivers/indev/evdev.h"

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void hal_init(void);
static int tick_thread(void *data);


/*********************
 *      DEFINES
 *********************/
/* select which demo you would like to execute */
#define COMPILE_WIDGET 1
//#define COMPILE_MUSIC 1
//#define COMPILE_KEYPAD 1


/**********************
 *   GLOBAL FUNCTIONS
 **********************/
int main(int argc, char **argv)
{
    (void)argc; /*Unused*/
    (void)argv; /*Unused*/

    /*Initialize LVGL*/
    lv_init();

    /*Initialize the HAL (display, input devices, tick) for LVGL*/
    hal_init();

#ifdef COMPILE_WIDGET
    lv_demo_widgets();
#endif
#ifdef COMPILE_MUSIC
    lv_demo_music();
#endif
#ifdef COMPILE_KEYPAD
    lv_demo_keypad_encoder();
 #endif

    while(1) {
        /* Periodically call the lv_task handler.
         * It could be done in a timer interrupt or an OS task too.*/
        lv_timer_handler();
        usleep(5 * 1000);
    }

    return 0;
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
/**
 * Initialize the Hardware Abstraction Layer (HAL) for the LVGL graphics
 * library
 */
static void hal_init(void)
{
#if USE_DRM
    drm_init();
#endif
#if USE_SDL
    sdl_init();
#endif

    /* Tick init.
     * You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about
     * how much time were elapsed Create an SDL thread to do this*/
 #if USE_SDL
    SDL_CreateThread(tick_thread, "tick", NULL);
#endif

    /* Create a display buffer */
    static lv_disp_draw_buf_t disp_buf1;

#if USE_DRM
    static lv_color_t buf1_1[128 * 1024];
    lv_disp_draw_buf_init(&disp_buf1, buf1_1, NULL, 128 * 1024);
#endif
#if USE_SDL
    static lv_color_t buf1_1[SDL_HOR_RES * 100];
    lv_disp_draw_buf_init(&disp_buf1, buf1_1, NULL, SDL_HOR_RES * 100);
#endif

    /*Create a display*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv); /*Basic initialization*/
    disp_drv.draw_buf = &disp_buf1;
#if USE_DRM
    disp_drv.flush_cb   = drm_flush;
    lv_coord_t drm_width, drm_height;
    /* get size from DRM-KMS backend */
    uint32_t drm_dpi;
    drm_get_sizes(&drm_width, &drm_height, &drm_dpi);
    disp_drv.hor_res    = drm_width;
    disp_drv.ver_res    = drm_height;
#endif
#if USE_SDL
    disp_drv.flush_cb = sdl_display_flush;
    disp_drv.hor_res = SDL_HOR_RES;
    disp_drv.ver_res = SDL_VER_RES;
#endif
    fprintf(stderr, "SCREEN SIZE ----> %d x %d\n", disp_drv.hor_res, disp_drv.ver_res);
    lv_disp_t * disp = lv_disp_drv_register(&disp_drv);

    lv_theme_t * th = lv_theme_default_init(disp,
                                            lv_palette_main(LV_PALETTE_BLUE),
                                            lv_palette_main(LV_PALETTE_RED),
                                            LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT);
    lv_disp_set_theme(disp, th);

#if USE_EVDEV
    /* warning: EVDEV_NAME on lv_drv_conf.h MUST be adapted to the correct input devince on board */
    evdev_init();
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = evdev_read;
    lv_indev_drv_register(&indev_drv);
#endif

#if USE_SDL
    lv_group_t * g = lv_group_create();
    lv_group_set_default(g);

    /* Add the mouse as input device
     * Use the 'mouse' driver which reads the PC's mouse*/
    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 = sdl_mouse_read;
    lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);

    static lv_indev_drv_t indev_drv_2;
    lv_indev_drv_init(&indev_drv_2); /*Basic initialization*/
    indev_drv_2.type = LV_INDEV_TYPE_KEYPAD;
    indev_drv_2.read_cb = sdl_keyboard_read;
    lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv_2);
    lv_indev_set_group(kb_indev, g);

    static lv_indev_drv_t indev_drv_3;
    lv_indev_drv_init(&indev_drv_3); /*Basic initialization*/
    indev_drv_3.type = LV_INDEV_TYPE_ENCODER;
    indev_drv_3.read_cb = sdl_mousewheel_read;
    lv_indev_t * enc_indev = lv_indev_drv_register(&indev_drv_3);
    lv_indev_set_group(enc_indev, g);

    /* Set a cursor for the mouse*/
    LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
    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*/
#endif
}

/**
 * A task to measure the elapsed time for LVGL
 * @param data unused
 * @return never return
 */
static int tick_thread(void *data) {
    (void)data;

    while(1) {
 #if USE_SDL
        SDL_Delay(5);
 #endif
       lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
    }
    return 0;
}

/**
 * Use a custom tick source that tells the elapsed time in milliseconds.
 * It removes the need to manually update the tick with `lv_tick_inc()`
*/
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;
}

5.1.2. Configuration of the demonstration for LVGL (lv_demo_conf.h)[edit | edit source]

  • The file lv_demo_conf.h must be aligned with the template present in lv_demos/lv_demo_conf_template.h:
cp lv_demos/lv_demo_conf_template.h lv_demo_conf.h
  • Adapt the configuration:

Enable the demonstration configuration and enable following demonstrations : benchmark with widgets, keypad and music with lanscape .

Replace at the beginning of the file

#if 0 /*Set it to "1" to enable the content*/

with

#if 1 /*Set it to "1" to enable the content*/

Configure the following defines to select the demonstrations you want to build:

#define LV_USE_DEMO_WIDGETS        '''1'''
#define LV_USE_DEMO_KEYPAD_AND_ENCODER    '''1'''
#define LV_USE_DEMO_MUSIC      '''1'''
#define LV_DEMO_MUSIC_LANDSCAPE    '''1'''

5.1.3. Configuration of LVGL (lv_conf)[edit | edit source]

  • The file lv_conf.h must be aligned with the template present in lvgl/lv_conf_template.h:
cp lvgl/lv_conf_template.h lv_conf.h
  • Adapt the configuration

Enable the LVGL configuration, force the color depth to 32, and enable the font for the demonstration.

Replace at the beginning of the file

#if 0 /*Set it to "1" to enable the content*/

with

#if 1 /*Set it to "1" to enable content*/

Configure the following defines:

Force the color depth:

#define LV_COLOR_DEPTH     32

Modify the memory size to 128:

#define LV_MEM_CUSTOM      1
#define  LV_MEM_SIZE    (128U * 1024U)          /*[bytes]*/

Enable the font (adapt according to the fonts requested by the elements used in the demonstration):

#define LV_FONT_MONTSERRAT_8     '''1'''
#define LV_FONT_MONTSERRAT_10    '''1'''
#define LV_FONT_MONTSERRAT_12    '''1'''
#define LV_FONT_MONTSERRAT_14    '''1'''
#define LV_FONT_MONTSERRAT_16    '''1'''
#define LV_FONT_MONTSERRAT_18    '''1'''
#define LV_FONT_MONTSERRAT_20    '''1'''
#define LV_FONT_MONTSERRAT_22    '''1'''
#define LV_FONT_MONTSERRAT_24    '''1'''
#define LV_FONT_MONTSERRAT_26    '''1'''
#define LV_FONT_MONTSERRAT_28    '''1'''
#define LV_FONT_MONTSERRAT_30    '''1'''
#define LV_FONT_MONTSERRAT_32    '''1'''
#define LV_FONT_MONTSERRAT_34    '''1'''
#define LV_FONT_MONTSERRAT_36    '''1'''
#define LV_FONT_MONTSERRAT_38    '''1'''
#define LV_FONT_MONTSERRAT_40    '''1'''
#define LV_FONT_MONTSERRAT_42    '''1'''
#define LV_FONT_MONTSERRAT_44    '''1'''
#define LV_FONT_MONTSERRAT_46    '''1'''
#define LV_FONT_MONTSERRAT_48    '''1'''
#define LV_FONT_MONTSERRAT_12_SUBPX      '''1'''
#define LV_FONT_MONTSERRAT_28_COMPRESSED '''1'''  /*bpp = 3*/
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW '''1'''  /*Hebrew, Arabic, Perisan letters and all their forms*/
#define LV_FONT_SIMSUN_16_CJK            '''1'''  /*1000 most common CJK radicals*/
#define LV_FONT_UNSCII_8        '''1'''
#define LV_FONT_UNSCII_16       '''1'''
#define LV_FONT_FMT_TXT_LARGE   '''1'''
#define LV_USE_FONT_COMPRESSED  '''1'''
#define LV_USE_FONT_SUBPX       '''1'''
#define LV_USE_BIDI         '''1'''

To see the performance monitor, activate:

#define LV_USE_MEM_MONITOR 1

5.2. Proposed modifications on LVGL project for configuration 1 and 2 (SDL2 with GPU)[edit | edit source]

To adapt LVGL to the STM32MP1 board, some modifications are needed.
The following modifications are valid only for the SDL2 configuration.

5.2.1. Configuration for LVGL driver (lv_drv_conf.h)[edit | edit source]

  • The file for LVGL driver lv_drv_conf.h must be aligned with the template present in lv_drivers/lv_drv_conf_template.h
cp lv_drivers/lv_drv_conf_template.h lv_drv_conf.h
  • Adapt the configuration:

Enable the driver configuration, SDL configuration, and display size configuration:

Replace at begin of file

#if 0 /*Set it to "1" to enable the content*/

with

#if 1 /*Set it to "1" to enable content*/

Configure the following defines:

# define USE_SDL 1
#  define SDL_HOR_RES     800
#  define SDL_VER_RES     480
Info white.png Information
The size of screen must be adapted to the size and the orientation of screen present on board:
STM32MP157F-DK2: 800x400 (configuration 1 Wayland)
STM32MP157F-DK2: 400x800 (configuration 2 DRM KMS)
STM32MP157F-EV1: 1280x720
STM32MP135F-DK: 480x272
STM32MP257F-EV1:1024x600
STM32MP257F-EV1_HDMI:1920x1080
STM32MP257F-DK:1024x600
STM32MP257F-DK_HDMI:1920x1080

5.3. Proposed modifications on LVGL project for configuration 3 (direct DRM-KMS no GPU)[edit | edit source]

To adapt LVGL to the STM32MP1 board, some modifications are needed.
The following modifications are valid only for the direct DRM-KMS configuration.

5.3.1. Configuration for LVGL (lv_conf.h)[edit | edit source]

  • In the file lv_conf.h, for configuration without SDL, the modification of LV_TICK_CUSTOM is mandatory to provide a custom tick source:
#define LV_TICK_CUSTOM     1
#define LV_TICK_CUSTOM_INCLUDE  "stdint.h"
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (custom_tick_get())
Info white.png Information
You must implement the custom_tick_get function in your main code.

An example of implementation is provided in the main.c example present on this wiki page.


5.3.2. Configuration for LVGL driver (lv_drv_conf.h)[edit | edit source]

  • The file for LVGL driver lv_drv_conf.h must be aligned with the template present in lv_drivers/lv_drv_conf_template.h:
cp lv_drivers/lv_drv_conf_template.h lv_drv_conf.h
  • Adapt the configuration:

Enable the driver configuration, drm configuration, and EVDEV configuration:

Replace at the beginning of the file

#if 0 /*Set it to "1" to enable the content*/

with

#if 1 /*Set it to "1" to enable content*/

Configure the following defines:

#  define USE_DRM           1
#  define USE_EVDEV       1    
Info white.png Information
For EVDEV configuration, EVDEV_NAME MUST be adapted to the input device available on board:
#  define EVDEV_NAME   "/dev/input/event1" /* touch screen on STM32MP157F-DK2 */
#  define EVDEV_NAME   "/dev/input/event0" /* touch screen on STM32MP135F-DK */
#  define EVDEV_NAME   "/dev/input/event0" /* touch screen on STM32MP257F-EV1 */ 
#  define EVDEV_NAME   "/dev/input/event0" /* touch screen on STM32MP257F-DK */  

5.4. Adaptation of Makefile (Makefile)[edit | edit source]

In Makefile, the CFLAGS and LDFLAGS must be adapted to the usage of librdm instead of the SDL2 library:

CFLAGS ?= -O3 -I$(LVGL_DIR)/ $(WARNINGS)
LDFLAGS ?= -lm -ldrm

5.5. Adaptation of CMakeLists.txt (CMakeLists.txt)[edit | edit source]

The following configurations are possible in CMakeLists.txt:

  • Define options for each configuration:
option(STM32MP_LVGL_WAYLAND_SDL2_GPU BOOLEAN OFF)
option(STM32MP_LVGL_DRM_KMS_SDL2_GPU BOOLEAN OFF)
option(STM32MP_LVGL_DIRECT_DRM_KMS_NOGPU BOOLEAN ON)
  • Define the board to test
#set(STM32MP_BOARD "STM32MP157F_DK2")
#set(STM32MP_BOARD "STM32MP135F_DK")
set(STM32MP_BOARD "STM32MP257F_EV1")
#set(STM32MP_BOARD "STM32MP257F_EV1_HDMI")
#set(STM32MP_BOARD "STM32MP257F_DK")
#set(STM32MP_BOARD "STM32MP257F_DK_HDMI")


  • Define target_compile_definitions for each configuration and board:
  • Build submodules with CMake:
add_subdirectory(lvgl)
add_subdirectory(lv_drivers)
add_subdirectory(lv_demos)
  • Add libraries:
target_link_libraries(main libdrm.so)
target_link_libraries(main libSDL2-2.0.so)

6. References[edit | edit source]

"LVGL official web site"[1]
"LVGL Get Started"[2]
"LVGL demos"[3]
"LVGL demos github" [4]
"LVGL project examples"[5]
"LVGL learning course"[6]
"LVGL forum"[7]
"SDL official web site"[8]
"Wayland official web site"[9]