LVGL Port for Linux Framebuffer in Beaglebone Black with Debian Buster

I’m starting to learn this excellent library. I own an old Beaglebone Black, with 2GB EMMC memory. Under these conditions, the installation of a system with a window manager and applications is quite limited. I was successful in porting the library to this platform, but I had to discover some things that are not clear in the documentation:

1- When I cloned the repository to my machine and tried to compile the library, I got errors. You must also clone the library repositories (LVGL), drivers (lv_drivers) and examples (lv_examples) as subdirectories of the port for linux framebuffer.

2- You must install libsdl, according to the installation guidelines for the micropython port (I had not installed it before and there were compilation errors due to lack of SDL): sudo apt-get install build-essential libreadline-dev libffi-dev git pkg-config libsdl2-2.0-0 libsdl2-dev python

3- I haven’t compiled any of my own projects yet. I just succeeded in compiling the library demo. But as I understand it, a project of its own needs to have in its subdirectory the repositories lv_drivers and lvgl to be compiled.

4- I’m trying to figure out how to make the touchscreen work without using the X server. The touchscreen present on the LCD is not even detected. But my touchpad keyboard does. I just haven’t found any way to use it with the library yet.

5- When I change the settings in lv_drv_conf.h, I get compilation errors. I already changed the USE_LIBINPUT and USE_EVDEV sections, putting the correct address (/ dev / event1) I get compilation errors.
lv_drivers / indev / libinput.c: 19: 10: fatal error: libinput.h: File or directory does not exist
#include <libinput.h>

6- I ran sudo apt install libelput1 libinput-bin libinput-dev libinput-tools libinput10

7- New errors, this time related to the device configuration:
libinput.c :(. text + 0x28): reference not defined for “libinput_device_unref”
/ usr / bin / ld: libinput.c :(. text + 0x2e): reference not defined for “libinput_path_remove_device”
/ usr / bin / ld: libinput.c :(. text + 0x3a): reference not defined for “libinput_path_add_device”
/ usr / bin / ld: libinput.c :(. text + 0x44): reference not defined for “libinput_device_ref”
/ usr / bin / ld: lv_drivers / indev / libinput.o: in the “libinput_init” function:
libinput.c :(. text + 0x90): reference not defined for “libinput_path_create_context”
/ usr / bin / ld: libinput.c :(. text + 0x9c): reference not defined for “libinput_device_unref”
/ usr / bin / ld: libinput.c :(. text + 0xa2): reference not defined for “libinput_path_remove_device”
/ usr / bin / ld: libinput.c :(. text + 0xae): reference not defined for “libinput_path_add_device”
/ usr / bin / ld: libinput.c :(. text + 0xb8): reference not defined for “libinput_device_ref”
/ usr / bin / ld: libinput.c :(. text + 0xc6): reference not defined for “libinput_get_fd”
/ usr / bin / ld: lv_drivers / indev / libinput.o: in the “libinput_read” function:
libinput.c :(. text + 0x12e): reference not defined for “libinput_dispatch”
/ usr / bin / ld: libinput.c :(. text + 0x134): reference not defined for “libinput_get_event”
/ usr / bin / ld: libinput.c :(. text + 0x166): reference not defined for “libinput_event_destroy”
/ usr / bin / ld: libinput.c :(. text + 0x16c): reference not defined for “libinput_get_event”
/ usr / bin / ld: libinput.c :(. text + 0x176): reference not defined for “libinput_event_get_type”
/ usr / bin / ld: libinput.c :(. text + 0x186): reference not defined for “libinput_event_get_touch_event”
/ usr / bin / ld: libinput.c :(. text + 0x198): reference not defined for “libinput_event_touch_get_x_transformed”
/ usr / bin / ld: libinput.c :(. text + 0x1b2): reference not defined for “libinput_event_touch_get_y_transformed”

You only need one of libinput or evdev, not both. I’d suggest using evdev since it doesn’t need any extra libraries.

Most of the repositories require you to download submodules. I’ve added a note here: https://github.com/lvgl/lv_port_linux_frame_buffer/commit/fc866ce725b89fbab8199a44373ea6b10fd8acab

You only need SDL if you’re using the PC simulator. The framebuffer port shouldn’t need SDL.

I tried both ways separately: evdev and libinput. With evdev, it didn’t show any errors, but it still doesn’t work.

Using evtest I can detect the touchpad functioning, even without the X installed. But I couldn’t get the touchpad to work in the demo.

There are some touchpad resolution and calibration settings that I haven’t touched yet. I also enabled keyboard and mouse in the lv_drv_conf.h file, but I still haven’t been able to make it work.

But I am assuming that evdev support is enabled in the demo … I just saw this thread here: https://github.com/lvgl/lvgl/issues/842 and thought that maybe the generated demo file does not detect events from evdev … I’ll check it out.

Another thing … anything I type on the keyboard is not captured by the demo, but by bash. When I type a linux command, the interface rendering is broken and the shell erase the interface. Could it be something not enabled in the demo?

This will be my Covid task. So I will keep posting here my experiences and errors, ok?

Did you initialize the driver using evdev_init? Did you register it with lv_indev_drv_register?

I think I lacked some contextual information about what I’m doing here. For now I have installed the library and am studying the sample files, changing some settings to see if I can make the widget demo work. I just noticed that in the main.c file there is no include for evdev. That’s probably why the demo doesn’t detect the touchpad. I’ll read the documentation and see if I can implement this in the demo to see if it works.

I am impressed by the speed and low memory usage. It will help me a lot in several projects that I’m playing. As soon as I am able to make these adjustments, I will test on Orange Pi (which is the platform I use most here).

Hello,
I start work today on the same stuff. Have BeagleBone Black, Rev C, Debian 4.19.94-ti-r64 #1buster on it. Have a 1024x600 LCD ( HDMI ) with optical touch (USB). Works fine on RPI.
I need the PRU units, so RPI is not a possible solution.
Was able to compile the downloaded files ( change only in lv_conf.h #define LV_HOR_RES_MAX (1024) and #define LV_VER_RES_MAX (600).
./demo works … output is very fast, but it doesn’t fit on the screen. Looks like there is a scale active.
Want to fix that first.

v_port_linux_frame_buffer$ ./demo 
The framebuffer device was opened successfully.
1024x600, 16bpp
The framebuffer device was mapped to memory successfully.

Is there a to do list for BeagleBone available?
I’m very impressed about the speed. I like it.

Thanks for any hint
Pepito

I’m able to compile and link “lv_port_linux_frame_buffer” on BeagleBone Black.
It’s possible to execute ./demo.
As I wrote already, it looks like the screen size is not correct.
If I change 1024 to 800 … I have a black stripe at the right side … expected, clear. Just to verify that my values are used.
I specified 32bpp but ./demo outputs 16bpp. May be that’s first failure of my setup.
/**

  • @file lv_conf.h

*/

/*
 * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
 */

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

#ifndef LV_CONF_H
#define LV_CONF_H
/* clang-format off */

#include <stdint.h>

/*====================
   Graphical settings
 *====================*/

/* Maximal horizontal and vertical resolution to support by the library.*/
// #define LV_HOR_RES_MAX          (480)
// #define LV_VER_RES_MAX          (320)
#define LV_HOR_RES_MAX          (1024)
#define LV_VER_RES_MAX          (600)

/* Color depth:
 * - 1:  1 byte per pixel
 * - 8:  RGB233
 * - 16: RGB565
 * - 32: ARGB8888
 */
#define LV_COLOR_DEPTH     32

Think it makes only sense to make the next step, in case the first one is definitely ok …
otherwise it will end up in endless story.
Has anybody a good idea, why the LV_COLOR_DEPTH 32 is ignored?
Thanks in advance for help
Pepito

The BPP it displays is read from the Linux framebuffer information. If Linux is reporting that the framebuffer is 16bpp, I recommend configuring LV_COLOR_DEPTH to also be 16. Things are generally more stable that way.

Thank you very much
Pepito

Now it works as it should be. 16bpp was the key. Thanks again.
Next step is optical touch, connected by USB.
Any hint? I read the previous posts, hope I can make it work.
Pepito

Touch is not working.
For that I need help
Pepito

You’re probably looking for the evdev driver. To start with I would look at the available event devices (ls /dev/input/event*) and find out which one is associated with your touchscreen. After that, you can configure it in lv_drv_conf.h, and it should work out of the box (once you initialize and register an input device).

Hi,
I’m using your demo code. Output is perfect.
But touch is not working.

ls -als /dev/input/event0
0 crw-rw-r-- 1 root input 13, 64 May 29 01:35 /dev/input/event0
I tried
1.)
#ifndef USE_LIBINPUT

define USE_LIBINPUT 1

#endif

#if USE_LIBINPUT

define LIBINPUT_NAME “/dev/input/event0” /You can use the “evtest” Linux tool to get the list of devices and test them/

#endif /USE_LIBINPUT/

2.)

#ifndef USE_EVDEV

define USE_EVDEV 1

#endif

#if USE_EVDEV

define EVDEV_NAME “/dev/input/event0” /You can use the “evtest” Linux tool to get the list of devices and test them/

define EVDEV_SWAP_AXES 0 /Swap the x and y axes of the touchscreen/

define EVDEV_SCALE 0 /* Scale input, e.g. if touchscreen resolution does not match display resolution */

if EVDEV_SCALE

define EVDEV_SCALE_HOR_RES (4096) /* Horizontal resolution of touchscreen */

define EVDEV_SCALE_VER_RES (4096) /* Vertical resolution of touchscreen */

endif /EVDEV_SCALE/

define EVDEV_CALIBRATE 0 /Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis/

if EVDEV_CALIBRATE

define EVDEV_HOR_MIN 3800 /If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted/

define EVDEV_HOR_MAX 200

define EVDEV_VER_MIN 200

define EVDEV_VER_MAX 3800

endif /EVDEV_SCALE/

#endif /USE_EVDEV/

Not at the same time, clear :slight_smile:
sudo fuser -v /dev/input/event0
USER PID ACCESS COMMAND
/dev/input/event0: root 956 F… systemd-logind
What do you think, is the device blocked?
sudo evtest /dev/input/event0
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: “tps65217_pwr_but”
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 116 (KEY_POWER)
Properties:
Testing … (interrupt to exit)
Any idea … ?
Thanks and have a good day
Pepito

Is event0 the correct device? There are often multiple, and it looks like you may have chosen the power button, not the touchscreen.

Aside from that ensure that you are calling evdev_init and registering the device:

    evdev_init();
    /*Initialize and register an input device*/
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);          /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = evdev_read;         /*This function will be called periodically (by the library) to get the mouse position and state*/
    lv_indev_drv_register(&indev_drv);

Thank you, I’m going to check that.
BTW, is some kind of simple “reference” template available, e.g. to only test and calibrate touch?
Have the feeling I’m not the only one :wink:
Thanks again
Pepito

I add the the code you sent to main.c, just before lv_demo_widgets(); is called
The function evdev_init() is not existing.

In lv_drv_conf.h I have the following:

ifndef USE_EVDEV
#define USE_EVDEV 1
#endif

#if USE_EVDEV
#define EVDEV_NAME “/dev/input/event0” /You can use the “evtest” Linux tool to get the list of devices and test them/
#define EVDEV_SWAP_AXES 0 /Swap the x and y axes of the touchscreen/

#define EVDEV_SCALE 0 /* Scale input, e.g. if touchscreen resolution does not match display resolution /
#if EVDEV_SCALE
#define EVDEV_SCALE_HOR_RES (4096) /
Horizontal resolution of touchscreen /
#define EVDEV_SCALE_VER_RES (4096) /
Vertical resolution of touchscreen */
#endif /EVDEV_SCALE/

#define EVDEV_CALIBRATE 0 /Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis/
#if EVDEV_CALIBRATE
#define EVDEV_HOR_MIN 3800 /If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted/
#define EVDEV_HOR_MAX 200
#define EVDEV_VER_MIN 200
#define EVDEV_VER_MAX 3800
#endif /EVDEV_SCALE/
#endif /USE_EVDEV/

So I’m expecting the function should be generated …
make is complaining …
lv_port_linux_frame_buffer$ make
main.c: In function ‘main’:
main.c:32:5: warning: implicit declaration of function ‘evdev_init’; did you mean ‘fbdev_init’? [-Wimplicit-function-declaration]
evdev_init();
^~~~~~~~~~
fbdev_init
main.c:37:25: error: ‘evdev_read’ undeclared (first use in this function); did you mean ‘lv_fs_read’?
indev_drv.read_cb = evdev_read; /This function will be called periodically (by the library) to get the mouse position and state/
^~~~~~~~~~
lv_fs_read
main.c:37:25: note: each undeclared identifier is reported only once for each function it appears in
main.c: At top level:
main.c:52:10: warning: no previous prototype for ‘custom_tick_get’ [-Wmissing-prototypes]
uint32_t custom_tick_get(void)
^~~~~~~~~~~~~~~
make: *** [Makefile:34: main.o] Error 1

Question: How to get evdev_init() ?

Have a good day
Pepito

You need to #include "lv_drivers/indev/evdev.h".

Hi,
now it’s there.
But touch is still not operating.

./demo
The framebuffer device was opened successfully.
1024x600, 16bpp
The framebuffer device was mapped to memory successfully.
unable open evdev interface:: Permission denied
^C
peter@beaglebone:~/Ultraschall/GUI/lv_port_linux_frame_buffer$ sudo ./demo
The framebuffer device was opened successfully.
1024x600, 16bpp
The framebuffer device was mapped to memory successfully.

Going to change permissions. The good thing is … /dev/input/event0 is know … trying to read from it.
Pepito