LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.
Basically, every modern controller which is able to drive a display is suitable to run LVGL. The minimal requirements are:
<li> Static RAM usage: ~2 kB depending on the used features and object types</li>
<li> Stack: > 2kB (> 8 kB is recommended)</li>
<li> Dynamic data (heap): > 4 KB (> 48 kB is recommended if using several objects).
Set by <em>LV_MEM_SIZE</em> in <em>lv_conf.h</em>. </li>
<li> Display buffer: > <em>"Horizontal resolution"</em> pixels (> 10 × <em>"Horizontal resolution"</em> is recommended) </li>
<li> One frame buffer in the MCU or in an external display controller</li>
</ul>
<a href="https://www.tutorialspoint.com/cprogramming/c_pointers.htm">pointers</a>,
<a href="https://www.tutorialspoint.com/cprogramming/c_structures.htm">structs</a>,
<a href="https://www.geeksforgeeks.org/callbacks-in-c/">callbacks</a>.</li>
Note that memory usage may vary depending on architecture, compiler and build options.
The LVGL project (including all repositories) is licensed under MIT license. This means you can use it even in commercial projects.
It's not mandatory, but we highly appreciate it if you write a few words about your project in the My projects category of the forum or a private message to lvgl.io.
Although you can get LVGL for free there is a massive amount of work behind it. It's created by a group of volunteers who made it available for you in their free time.
To make the LVGL project sustainable, please consider contributing to the project. You can choose from many different ways of contributing such as simply writing a tweet about you using LVGL, fixing bugs, translating the documentation, or even becoming a maintainer.
All repositories of the LVGL project are hosted on GitHub: https://github.com/lvgl
You will find these repositories there:
The core repositories follow the rules of Semantic versioning:
Tags like vX.Y.Z
are created for every release.
The core repositories have at least the following branches:
master
latest version, patches are merged directly here.release/vX.Y
stable versions of the minor releasesfix/some-description
temporary branches for bug fixesfeat/some-description
temporary branches for featuresThe changes are recorded in CHANGELOG.md.
Before v8 the last minor release of each major series was supported for 1 year. Starting from v8, every minor release is supported for 1 year.
Version | Release date | Support end | Active |
---|---|---|---|
v5.3 | Feb 1, 2019 | Feb 1, 2020 | No |
v6.1 | Nov 26, 2019 | Nov 26, 2020 | No |
v7.11 | Mar 16, 2021 | Mar 16, 2022 | No |
v8.0 | 1 Jun, 2021 | 1 Jun, 2022 | Yes |
v8.1 | 10 Nov, 2021 | 10 Nov, 2022 | Yes |
v8.2 | 31 Jan, 2022 | 31 Jan, 2023 | Yes |
v8.3 | In progress |
You can ask questions in the forum: https://forum.lvgl.io/.
We use GitHub issues for development related discussion. You should use them only if your question or issue is tightly related to the development of the library.
Before posting a question, please ready this FAQ section as you might find answer to your issue here too.
Every MCU which is capable of driving a display via parallel port, SPI, RGB interface or anything else and fulfills the Requirements is supported by LVGL.
This includes:
LVGL needs just one simple driver function to copy an array of pixels into a given area of the display. If you can do this with your display then you can use it with LVGL.
Some examples of the supported display types:
See the Porting section to learn more.
LV_MEM_SIZE
.lv_disp_drv_t
, lv_indev_drv_t
and lv_fs_drv_t
are global or static
.lv_conf.h
(LV_USE_ASSERT_...
)lv_timer_handler()
Be sure you are calling lv_tick_inc(x)
in an interrupt and lv_timer_handler()
in your main while(1)
.
Learn more in the Tick and Timer handler sections.
Be sure you are calling lv_disp_flush_ready(drv)
at the end of your "display flush callback".
Probably there a bug in your display driver. Try the following code without using LVGL. You should see a square with red-blue gradient.
#define BUF_W 20
#define BUF_H 10
lv_color_t buf[BUF_W * BUF_H];
lv_color_t * buf_p = buf;
uint16_t x, y;
for(y = 0; y < BUF_H; y++) {
lv_color_t c = lv_color_mix(LV_COLOR_BLUE, LV_COLOR_RED, (y * 255) / BUF_H);
for(x = 0; x < BUF_W; x++){
(*buf_p) = c;
buf_p++;
}
}
lv_area_t a;
a.x1 = 10;
a.y1 = 40;
a.x2 = a.x1 + BUF_W - 1;
a.y2 = a.y1 + BUF_H - 1;
my_flush_cb(NULL, &a, buf);
Probably LVGL's color format is not compatible with your display's color format. Check LV_COLOR_DEPTH
in lv_conf.h.
If you are using 16-bit colors with SPI (or another byte-oriented interface) you probably need to set LV_COLOR_16_SWAP 1
in lv_conf.h.
It swaps the upper and lower bytes of the pixels.
You can disable all the unused features (such as animations, file system, GPU etc.) and object types in lv_conf.h.
If you are using GCC/CLANG you can add -fdata-sections -ffunction-sections
compiler flags and --gc-sections
linker flag to remove unused functions and variables from the final binary. If possible, add the -flto
compiler flag to enable link-time-optimisation together with -Os
for GCC or -Oz
for CLANG.
LV_MEM_SIZE
in lv_conf.h. This memory is used when you create objects like buttons, labels, etc.LV_MEM_SIZE
you can create objects only when required and delete them when they are not needed anymoreTo work with an operating system where tasks can interrupt each other (preemptively) you should protect LVGL related function calls with a mutex. See the Operating system and interrupts section to learn more.