This guide will walk you through the process of downloading, compiling, deploying, and debugging the official LVGL demos for VS Code. LVGL, or LittleVGL, is an open-source graphics library for embedded systems.
Requirements
Before you begin, ensure you have the following:
- A working and running ARM64-based CPU with the correct image and a static IP.
- Visual Studio Code installed. You can download it from here.
- Install the following packages using the terminal:
sudo apt-get update
sudo apt-get install build-essential gdb cmake ninja-build
Note: We're assuming you're using an i.Core MX8M Mini on our Open Frame C.Touch 2.0 with an LVDS Display 1280x800.
Project Setup
- Open a terminal and download the repository and its submodules:
git clone https://github.com/lvgl/lv_port_pc_eclipse.git -b release/v8.3 --recurse-submodules
- Once the repository is cloned, open it in VS Code with the command:
code lv_port_pc_eclipse/
VS Code Setup
- Navigate to the Extension view on the toolbar on the left (or use
Ctrl+Shift+X
) and search for c++. Install C/C++ Extension Pack.
- Project Customization:
- Key files in the repository layout:
lvgl
: The LVGL library with examples and demos.lv_drivers
: Display and input device drivers.lv_conf.h
: Configuration file for the LVGL library.lv_drv_conf.h
: Configuration file for the drivers.main.c
: Main file to initialize and start the application.
- Key files in the repository layout:
For our project we will need to customize some of these files.
To enhance performance, we customize lv_conf.h
by setting LV_USE_ASSERT_MEM_INTEGRITY
and LV_USE_ASSERT_OBJ
to 0
.
lv_conf.h:
/*-------------
* Asserts
*-----------*/
/*Enable asserts if an operation is failed or an invalid data is found.
*If LV_USE_LOG is enabled an error message will be printed on failure*/
#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/
#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
#define LV_USE_ASSERT_STYLE 1 /*Check if the styles are properly initialized. (Very fast, recommended)*/
#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/
In lv_drv_conf.h
, we set the correct resolution for the display.
lv_drv_conf.h:
#if USE_SDL || USE_SDL_GPU
# define SDL_HOR_RES 1280
# define SDL_VER_RES 800
We modify the driver lv_drivers/sdl/sdl.c
to enable fullscreen execution of the demo.
sdl.c:
#ifndef SDL_FULLSCREEN
# define SDL_FULLSCREEN 1
#endif
CMake Builder Setup
- Setup the CMake Extension:
- Press
Ctrl+Shift+P
to open the Command Palette and search forCmake: Edit User-Local CMake Kits
. - Edit the opened file cmake-tools-kits.json to define the kit for cross-compiling the demo.
- Press
[
{
"name": "GCC 7.5.0 x86_64-linux-gnu",
"compilers": {
"C": "/usr/bin/gcc",
"CXX": "/usr/bin/g++"
},
"isTrusted": true
},
{
"name": "Langdale - Arm64",
"toolchainFile": "/opt/fsl-imx-xwayland/6.1-langdale/sysroots/x86_64-pokysdk-linux/usr/share/cmake/armv8a-poky-linux-toolchain.cmake",
"isTrusted": true
}
]
- Build and Configure the Project:
- Open the Command Palette (
Ctrl+Shift+P
) and search for CMake: Configure. - Select the correct kit.
- Open the Command Palette (
Once the configuration is done, proceed to build the project by typing CMake: Build in the Command Palette.
This will generate a binary file named main for ARM64 in the directory bin.
Tasks Setup
- Create a new folder named .vscode and inside it a file named tasks.json.
- Populate it with the following tasks:
{
"version": "2.0.0",
"tasks": [
{
"label": "Deploy to Target",
"type": "shell",
"command": "scp ${workspaceFolder}/bin/main root@192.168.2.99:/home/root && ssh root@192.168.2.99 'chmod +x /home/root/main'",
"problemMatcher": [],
"presentation": {
"reveal": "silent"
}
},
{
"label": "Launch GDBSERVER on Target",
"type": "shell",
"command": "ssh root@192.168.2.99 'export DISPLAY=:0 && gdbserver 192.168.2.99:6969 main'",
"problemMatcher": [],
"presentation": {
"reveal": "silent"
}
}
]
}
In order to use the tasks you need to open the Command Palete and type Tasks: Run Task and select the desired one.
Note: Make sure that the target IP corresponds with the one from your machine.
In the following screenshots you can see an example on the ouput of the two tasks created:
Debugger Setup
- Create a new file inside the .vscode folder named launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Remote ARM64",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/main", // Path to the binary on the host PC
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/opt/fsl-imx-xwayland/6.1-langdale/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-gdb", // Path to the debugger on the host PC
"miDebuggerServerAddress": "192.168.2.99:6969", // GDB Server ip and port
"miDebuggerArgs": " -ex 'handle all print nostop noignore'",
"targetArchitecture": "arm64",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
Once the file has been created, you just need to press F5
to start the remote debugging session:
Now, the environment is ready to be used.
Appendix A - Image and Toolchain Creation
To begin, you'll need to create a Yocto image and toolchain. Yocto is a Linux distribution build tool.
-
Create the Yocto Image:
- The blueprint for the base Yocto image can be found in our meta-layer on GitHub.
- Refer to the recipe named engicam-evaluation-image-mx8.bb.
- Note: This guide is based on the Yocto Distribution named Langdale; syntax and output files may vary in different versions.
-
Update the image with the necessary packages using the recipe provided in engicam-evaluation-image-mx8-lvgl.bb.
require recipes-images/images/engicam-evaluation-image-mx8.bb IMAGE_FEATURES += " \ ssh-server-openssh \ " IMAGE_INSTALL += " \ libsdl2 \ libsdl2-image \ libsdl2-mixer \ libsdl2-net \ libsdl2-ttf \ libsdl \ libsdl-gfx \ libsdl-image \ libsdl-mixer \ libsdl-net \ libsdl-ttf \ " SDKIMAGE_FEATURES += "staticdev-pkgs"
-
Build the Image and Toolchain:
- Incorporate the provided recipe into your meta-layer.
- Build the image using the command:
bitbake engicam-evaluation-image-mx8-lvgl
- To build the toolchain, use:
bitbake engicam-evaluation-image-mx8-lvgl -c populate_sdk
- Install the Toolchain:
- Once built, navigate to the deployment directory:
cd <build dir>/tmp/deploy/sdk
- Run the installation script:
./fsl-imx-xwayland-glibc-x86_64-engicam-evaluation-image-mx8-lvgl-armv8a-imx8mm-icore-toolchain-6.1-langdale.sh
- Once built, navigate to the deployment directory:
Appendix B - Set Static IP
Setting a static IP is crucial for communication with your System on Module (SOM). Here's how to do it using systemd or Connman.
Systemd
-
Create Configuration File:
- Open the file
/etc/systemd/network/20-eth0.network
:vi /etc/systemd/network/20-eth0.network
- Add the following configuration:
[Match] Name=eth0 [Network] Address=192.168.9.99/24 IPv4LLRoute=true Gateway=192.168.9.1 DNS=8.8.8.8
- Open the file
- Enable Service:
- Enable the
systemd-networkd
unit:systemctl enable systemd-networkd.service
- Reboot the board for changes to take effect.
- Enable the
Connman
-
Identify Wired Interface:
- List available wired interfaces:
connmanctl services
- Select the appropriate interface (e.g.,
ethernet_d6df1c33e1eb_cable
).
- List available wired interfaces:
- Configure Static IP:
- Run the following commands:
connmanctl config <service> --ipv4 manual <ip address> <netmask> <gateway> connmanctl config <service> --nameservers <dns-addr>
- For example:
connmanctl config ethernet_d6df1c33e1eb_cable --ipv4 manual 192.168.9.99 255.255.255.0 192.168.9.1 connmanctl config ethernet_d6df1c33e1eb_cable --nameservers 8.8.8.8 2.2.2.2
- Run the following commands: