rlvgl is a modular, idiomatic Rust reimplementation of LVGL (Light and Versatile Graphics Library).
rlvgl preserves the widget-based UI paradigm of LVGL while eliminating unsafe C-style memory management and global state. This library is structured to support no_std environments, embedded targets (e.g., STM32H7), and simulator backends for rapid prototyping.
The C version of LVGL is included as a git submodule for reference and test vector extraction, but not linked or compiled into this library.
Goals
Package: rlvgl
- Preserve LVGL architecture and layout system
- Replace C memory handling with idiomatic Rust ownership
- Support embedded display flush/input via embedded-hal
- Enable widget hierarchy, styles, and events using Rust traits
- Use existing Rust crates where possible (e.g., embedded-graphics, heapless, tinybmp)
Features
- no_std + allocator support with simulator-friendly std features
- Modular workspace crates for core widgets, platform backends, UI helpers, API bindings, and i18n
rlvgl-creatorsupport for asset preparation, vendor database browsing, and STM32 BSP generation from CubeMX.iocfiles- Vendor chip database crates and generated STM BSP crates for board-aware tooling
- Flagship STM32H747I-DISCO demo covering DSI display, touch, SDRAM, SD/MMC, audio, and DMA2D-assisted rendering
- Motion, compositor, dirty-region, and accelerated blitting primitives for richer embedded UIs
- Pluggable display and input backends for both embedded targets and host simulation
- Optional Lottie support for dynamic playback and offline asset conversion workflows
Project Structure
- core – Widget base trait, layout, event dispatch
- widgets – Rust-native reimplementations of LVGL widgets
- platform – Display/input traits and HAL adapters
- ui – Higher-level UI components
- examples/apps/demo – Packaged demo application crate
- api – Shared ABI types for bindings and coprocessor integrations
- i18n – Compile-time translations with runtime-selectable locale blobs
- chipdb – Vendor chip databases used by creator and BSP generation
- chips/stm/bsps – Generated STM32 BSP modules
- rlvgl-creator – Asset and BSP workflows for command-line and UI tooling
- examples – Sample applications and board demos
- docs – Project documentation and task lists
- lvgl – C submodule (reference only)
What's New in 0.1.9
rlvgl-creatornow covers vendor import, board IR generation, and Rust BSP rendering with bundled alternate-function databases.- STM32H747I-DISCO moved from bring-up into a flagship demo path with dual-core startup, DSI display, touch, storage, audio, and richer UI flows.
- The rendering stack gained
EventWindow, compositor/save-under behavior, motion helpers, DMA2D acceleration, and display-pipeline fixes for smoother presentation. - The workspace now includes first-class i18n, API, chip database, and generated BSP crates alongside the core UI crates.
Vendor chip databases
Vendor-specific board definitions live in the chipdb/ crates. The
tools/gen_pins.py helper aggregates raw vendor inputs into JSON
blobs, while tools/build_vendor.sh orchestrates generation and stamps
license files. When building a vendor crate, set RLVGL_CHIP_SRC to the
directory containing these JSON files so the build script can embed them
via include_bytes!.
STM32CubeMX BSP generation 🆕
rlvgl-creator 🆕 converts STM32 CubeMX .ioc projects into board support
stubs. Generated modules ship in
rlvgl-bsps-stm 🆕. The older board
overlay support remains but is deprecated.
BSP Generator (rlvgl-creator 🆕)
rlvgl-creator 🆕 offers a two-stage pipeline for board support packages:
- Import vendor project files (e.g., STM32CubeMX
.ioc, NXP.mex, RP2040 YAML). Each adapter mines the vendor data and emits a small, vendor-neutral YAML IR describing clocks, pins, DMA and peripherals. - Generate Rust initialization code by rendering MiniJinja templates against the IR. Users may choose from built-in template packs or provide their own.
The STM32CubeMX adapter also parses PLL multipliers and peripheral kernel clock selections so that clock setup can be generated alongside pin configuration.
No per-chip tables are maintained. Class-level rules are reused across
instances and vendors. Alternate functions are derived from embedded vendor
databases generated from the official XML sources; no external JSON is
required at generation time. Reserved SWD pins (PA13, PA14) are rejected
unless explicitly allowed.
Typical flow:
Alternate-function numbers are computed from the embedded database at runtime
by rlvgl-creator, so there is no need to generate or pass a JSON file.
To package vendor chip databases for testing or publishing, run:
RLVGL_CHIP_SRC=chipdb/rlvgl-chips-stm/generated
For a full asset workflow overview see the rlvgl-creator 🆕 README. Command details live in docs/CREATOR-CLI.md.
IR schema
The import step emits a concise YAML specification describing the board:
mcu: STM32H747XIHx
package: LQFP176
power:
clocks:
sources:
pll:
pll1:
kernels:
pinctrl:
- group: usart1-default
signals:
-
-
peripherals:
usart1:
class: serial
params:
pinctrl:
reserved_pins:
Field summary:
mcu,package– identifiers from the vendor project.power– supply configuration; values map directly to HAL calls.clocks– input frequencies (sources), PLL multipliers (pll) and per‑peripheral kernel selections (kernels).pinctrl– groups of pins with their functions, alternate functions, pulls and speeds.peripherals– map of peripheral instances keyed by name (usart1), each with aclass(e.g.serial) and optionalparams.dma,interrupts– optional arrays describing DMA requests and IRQ priorities.reserved_pins– pins that must not be reconfigured (e.g. SWD).
Template helpers
MiniJinja templates can use the following filters:
pin_var– convert a pin likePA9into the variable namepa9.periph_num– extract trailing digits from a peripheral name (usart12→12).af_alt– render an alternate-function number forinto_alternate::<AF>()(7→<7>).
Users may supply custom templates by pointing --templates at any
directory; the filters above are always available.
See docs/TODO-CREATOR-BSP.md for remaining work.
Status
As-built. See docs for component-by-component progress and outstanding tasks.
v0.1.9 shifts rlvgl from a core-library-first workspace toward a fuller
embedded UI product stack. The main areas of growth are the creator/BSP
pipeline, the STM32H747I-DISCO showcase target, and the runtime pieces needed
for more polished embedded applications.
Quick Example
use Rect;
use Label;
Testing
Run host-based tests with the default toolchain:
Cross-target tests (e.g., thumbv7em-none-eabihf) require a linker. Cargo
defaults to arm-none-eabi-gcc, but you can avoid installing GCC by adding
the rust-lld component and configuring:
[]
= "rust-lld"
See docs/CROSS-TESTING.md for troubleshooting tips.
Coverage
LLVM coverage instrumentation is configured via .cargo/config.toml and the
coverage target in the Makefile. Run make coverage to execute the tests
with instrumentation and generate an HTML report under ./coverage/.
rlvgl crate
- The link above is for the top crate which bundles the others and includes the simulator.
- rlvgl-core crate
- rlvgl-widgets crate
- rlvgl-platform crate
- rlvgl-ui crate
- rlvgl-i18n crate
Run the following Cargo command in your project directory:
Or add the following line to your Cargo.toml:
= "0.1.9"
Community
Dockerhub
The build image used by the Github worflow for this repo is publiclly available on Dockerhub.
Consult the Dockerfile for details on the build environment.
Other useful helper scripts may be found in /scripts.
License
rlvgl is licensed under the MIT license. See LICENSE for more details. Third-party license notices are summarized in NOTICES.md.
More Information
For more information, visit softoboros.com.