LVGL 9.2 port (draft — tcan v2.0 migration)#206
Draft
mLupine wants to merge 3 commits intolvgl:masterfrom
Draft
Conversation
Replace the LVGL 8.3.7 git submodule (lvgl-sys/vendor/lvgl) with a
vendored drop of the LVGL v9.2.2 release tarball at
lvgl-sys/vendor/lvgl-9.2/ (SHA256 129b4e00...). Add a vendored
lv_conf.h derived from upstream's 9.2 template with LV_USE_SNAPSHOT=1
(needed for DISP-03 pixel parity capture in Plan 04-09).
Rewrite lvgl-sys/build.rs for the LVGL 9 layout: cc compiles every .c
under vendor/lvgl-9.2/src + the lvgl_sys color shim; bindgen runs
against shims/lvgl_sys.h with allowlists for lv_.* / LV_.*. The legacy
lv_drivers (SDL/Linux backends) and the rust_timer/drivers feature
flags are kept as no-ops -- ESP-IDF v6 path uses esp_lvgl_port.
Update the lvgl_sys color shim for LVGL 9 lv_color_t (BGR888 native;
.red/.green/.blue fields). _LV_COLOR_GET_A returns 0xFF (alpha is in
lv_color32_t now). The lvgl-sys sanity test switches from LVGL 8's
lv_disp_get_hor_res to LVGL 9's lv_display_get_horizontal_resolution.
Bump lvgl-sys + lvgl crate versions to 0.6.2-mLupine-lvgl-9 to mark
the fork divergence (Cargo's prerelease-tag must be requested
explicitly, which is what we want from path consumers).
Add an inner .cargo/config.toml so 'cargo build' from inside the
fork defaults to host (instead of inheriting the parent's xtensa-
esp32s3-espidf target pin). Cross-compile target config is preserved.
Bindings verification:
grep lv_display_t bindings.rs -> 68 occurrences
grep lv_image_dsc_t bindings.rs -> 13 occurrences
grep lv_disp_drv_t bindings.rs -> 0 (LVGL 8 type fully absent)
grep lv_snapshot_take bindings.rs -> 3
lv_color_t struct = { blue: u8, green: u8, red: u8 } (LVGL 9 BGR888)
cargo build -p lvgl-sys --target aarch64-apple-darwin -> Finished
Replace the LVGL 8 lvgl/src/ tree (4083 LOC across drivers, input_device,
embedded_graphics integration, full widget catalog, lv_core/style builder,
support.rs Color/LvError module, timer.rs, font module, allocator) with a
slim hand-authored LVGL 9 surface scoped to what lupin-display actually
needs per CONTEXT.md D-29..D-30:
src/lib.rs -- crate root with re-exports
src/color.rs -- Color (RGB888) + ColorFormat enum (RGB565, RGB888,
ARGB8888, I1, Native) mapped to lv_color_format_t
src/display.rs -- Display wrapping *mut lv_display_t with both
Display::create() AND Display::from_raw() (D-29-a:
wraps the pointer returned by lvgl_port_add_disp);
set_buffers/set_color_format/set_flush_cb following
LVGL 9's create-then-configure flow; LVGL 9 flush
cb signature uses *mut u8 (untyped byte buffer),
NOT *mut lv_color_t -- driver interprets via the
per-display color format
src/obj.rs -- thin Obj<*mut lv_obj_t> wrapper + screen_active()
(lv_screen_active() in 9.x; old lv_scr_act() macro
still works but the new spelling is preferred)
src/screen.rs -- non-owning Screen view obtained from
lv_display_get_screen_active
src/image_dsc.rs -- ImageDsc / ImageHeader type aliases over LVGL 9's
lv_image_dsc_t (renamed from LVGL 8's lv_img_dsc_t,
layout-compatible)
src/widgets/mod.rs -- pub mod label; pub mod image;
src/widgets/label.rs -- Label::{new,set_text,set_text_static}
src/widgets/image/mod.rs -- Image::{new,set_src_dsc,set_src_raw}
using lv_image_create + lv_image_set_src
src/snapshot.rs -- Snapshot wrapper over lv_snapshot_take +
lv_draw_buf_destroy on Drop. Required for Plan
04-09 DISP-03 pixel-byte parity capture
(LV_USE_SNAPSHOT=1 is set in vendored lv_conf.h
per Task 1)
build.rs is now a no-op -- the LVGL 8 lvgl-codegen pipeline scraped 8.x
header signatures and emitted widgets/generated.rs; LVGL 9 widget
signatures don't match those patterns (lv_obj_t * lv_image_create vs.
lv_obj_t * lv_btn_create -- name conventions differ enough that
re-targeting codegen needs work that's tracked as upstream-PR follow-up
rather than blocking this plan). The widget surface lupin-display
needs (label + image) is small enough that hand-authored wrappers are
clearer.
Cargo.toml: drop embedded-graphics/cstr_core/bitflags/paste/ctor (all
LVGL-8-coupled), drop the example matrix (every example used the
lv_drivers SDL backend), drop nightly/lvgl_alloc/custom_allocator/
unsafe_no_autoinit/embedded_graphics features. Bump the default
feature set to [] (no embedded-graphics).
Add _LV_COLOR_.* allowlist to lvgl-sys/build.rs so bindgen exposes the
custom color-channel accessors from shims/lvgl_sys.h (these don't match
the lv_.* allowlist because they start with an underscore-prefix LV).
Acceptance regex (Plan 04-02 Task 2):
grep -q lv_image_dsc_t lvgl/src/widgets/image/mod.rs -> match
grep -q lv_display_t lvgl/src/display.rs -> match
! grep -rq lv_disp_drv_t lvgl/src/ -> 0 matches
grep -rn lv_img_dsc_t lvgl/src/ -> 0 matches
grep -r snapshot_take lvgl/src/ -> 7 matches
grep -r from_raw lvgl/src/display.rs -> from_raw present
cargo build -p lvgl --target aarch64-apple-darwin -> Finished
When cross-compiling lvgl-sys for xtensa-esp32s3-espidf the C build (cc-rs) succeeds because xtensa-esp-elf-gcc is on PATH and provides its own includes implicitly. Bindgen then invokes a separate clang with -target xtensa-esp32s3-espidf and that clang fails with 'inttypes.h file not found' because no sysroot is supplied. Resolve by shelling out to xtensa-esp-elf-gcc -print-sysroot at build time and adding -I<sysroot>/include to the bindgen clang args. Skipped silently when the toolchain isn't on PATH (host builds).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LVGL 9.2 port
This is a draft PR porting
lv_binding_rustfrom LVGL 8.x to LVGL 9.2.x, opened as a conversation-starter rather than a merge-ready submission.Motivation
I’m rewriting an ESP-IDF v6 firmware stack (originally Arduino-era C++) in Rust, and need LVGL 9.2 Rust bindings because
esp_lvgl_port2.3 (shipping with IDF v6) targets LVGL 9.x exclusively.Upstream
maintargets LVGL 8.x. Issue #195 has been open since Feb 2025 asking for LVGL 9 support, with zero PRs in flight. This PR establishes a minimum-viable 9.x surface so downstream projects can unblock; broader API restoration (embedded-graphics integration,lv_driversSDL/Linux backends, the full widget catalog, the style builder) is explicit follow-up work.Branch
mLupine/lv_binding_rust-fork@mLupine-lvgl-9d83b3740(HEAD at time of fork).Changes summary
Three commits (full messages on the branch):
be56b12— vendor LVGL 9.2.2 + lvgl-sys bindgen against 9.xvendor/lvgl,vendor/lv_drivers) with a vendored drop of LVGL v9.2.2 underlvgl-sys/vendor/lvgl-9.2/.lvgl-sys/vendor/include-9.2/lv_conf.h(template-derived,LV_USE_SNAPSHOT=1).lvgl-sys/build.rsfor the LVGL 9 source layout (cccompiles every.cundervendor/lvgl-9.2/src;bindgenruns againstshims/lvgl_sys.hwith allowlistslv_.*/LV_.*/_LV_COLOR_.*).lv_color_t({blue,green,red}field accessors;_LV_COLOR_GET_Areturns0xFFsince alpha now lives inlv_color32_t).lvgl-syssanity test fromlv_disp_get_hor_res(LVGL 8) tolv_display_get_horizontal_resolution(LVGL 9).0.6.2-mLupine-lvgl-9.4861b1b— portlvglcrate safe wrapper to LVGL 9.2 (minimum-viable)lvgl/src/tree with a slim hand-authored 9.x surface scoped to what downstreamlupin-displayneeds:display.rs—Display::create+Display::from_rawfor interop withesp_lvgl_port::lvgl_port_add_dispreturns; LVGL-9 byte-buffer flush-callback adapter.color.rs—Color+ColorFormatenum mappinglv_color_format_t.obj.rs,screen.rs— thin handles.image_dsc.rs— alias overlv_image_dsc_t(renamed from LVGL 8'slv_img_dsc_t).widgets/{label,image/mod}.rs.snapshot.rs—lv_snapshot_take+lv_draw_buf_destroy(for RGB565 capture over UART).build.rsbecomes a no-op — LVGL 8lvgl-codegenwidget pipeline is unused in this PR (regenerating against LVGL 9 widget signatures is separate follow-up work).embedded-graphics/cstr_core/bitflags/paste/ctorand the LVGL 8 example matrix fromCargo.toml.2ea8ccd— teach lvgl-sys/build.rs to find xtensa newlib headersbindgeninvokes a separate clang with-target xtensa-esp32s3-espidfthat fails on<inttypes.h>because no sysroot is supplied; resolved by shelling out toxtensa-esp-elf-gcc -print-sysrootat build time and adding-I<sysroot>/includeto bindgen's clang args (silently skipped when the xtensa toolchain isn't on PATH).Verification
cargo build -p lvgl --target aarch64-apple-darwin→ Finished.cargo +esp build -p lvgl --target xtensa-esp32s3-espidfon ESP-IDF v6 → Finished (one harmlessimproper_ctypeswarning on a varargsva_listfield).Status
This PR is draft pending (any of these are welcome as conversation points, not blockers):
lv_binding_rustmaintainers — I'd prefer to converge on upstream's preferred shape for theDisplay::from_raw_display/ flush-callback / color-format-awareness seams rather than upstream ad-hoc choices.embedded_graphics+lv_driversintegrations are deliberately not included.input_devicefamily — LVGL 9 removedlv_indev_drv_t; theinput_devicemodule is not ported.Happy to split this into smaller PRs if that's easier to review (vendor-drop + lvgl-sys as one, safe wrapper as another, build.rs xtensa fix as a third).
Un-forking plan
Once this (or an equivalent) upstream PR merges and a released
lvgl = "…"crate tracks LVGL 9.2, downstreamtcan-rustreverts its.deps/lv_binding_rustsubmodule and consumes the crate directly.Summary by cubic
Ports the Rust bindings to LVGL 9.2.2 and ships a minimal
lvgl9.x API (display, color, label, image, snapshot) to unblock ESP‑IDF v6 /esp_lvgl_portusers.New Features
lvgl-sys/vendor/lvgl-9.2/; updatedlvgl-sysbuild (compile new src tree,bindgenallowlists) and color shims; tests uselv_display_get_*_resolution.lvgl9 API:Display::{create, from_raw}, byte-buffer flush adapter,Color/ColorFormatmapped tolv_color_format_t, widgetsLabelandImage, andSnapshot; dropped 8.x codegen, examples, and deps.bindgen; added inner.cargo/config.tomlso local builds default to host.Migration
lv_color_tis RGB888 (BGR fields); alpha lives inlv_color32_t.lv_display_*APIs (e.g.,lv_display_get_horizontal_resolution). The 8.xlv_indev_drv_tpath is not ported.embedded-graphics,lv_driversbackends, and the full widget/style builder surface. Only Label, Image, and Snapshot are available today.Written for commit 2ea8ccd. Summary will update on new commits.