display_driver: LVGL on one multimer timer that asks LVGL when to come back - #22
Merged
Merged
Conversation
…o come back One ONE_SHOT timer runs lv.timer_handler() and re-arms itself to what LVGL returns, bounded by LVGL_PERIOD_MS and the yield rule from #15 and #19. A PARTIAL panel presents from the display's own frame clock, only after a flush; LVGL's refresh timer is set to the display's frame period. The async mode and the App-timer subscription go: multimer delivers on the host's own loop where the host owns one. Driver construction runs under multimer.hold(), so no callback can land while draw buffers are created.
LVGL presents once per frame from the frame clock and reads its indevs itself; the App's refresh timer and service tick stand down while the driver runs (pause_refresh, pause_polling) and come back at shutdown.
… ask; tests on the new loop
A pass that took longer than the delay LVGL asked for ("again now" after
any real work counts) is followed by at least one period and, when it was
longer than a period, by min(pass, max_yield_ms). The starvation test runs
the real _on_timer on a virtual clock with a stand-in multimer Timer, keeps
the #15 and #19 cases, adds the calibration (the model reproduces the
board's ~87 % without the hold) and a check that an idle LVGL is run when it
asks, not on a poll. The nesting test gains the same stand-in.
This was referenced Sep 26, 2026
The 10 ms lvgl.host_pump timer drains a host window's event queue for every driver's virtual devices. A panel with a touch controller has none, and on the T-Embed the timer fired 100 times a second for an empty loop (multimer.report() showed it beside the real ones). It is created only when a driver has virtual devices.
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.
display_driver.pyruns LVGL on onemultimerONE_SHOT timer that re-arms itself to whatlv.timer_handler()returns, bounded by a 10 ms period so input is read at least that often. A pass that outran what LVGL asked for is followed by at least a period off, and a pass longer than a period bymin(pass, max_yield_ms): the rule of #15 and #19, now in one place (event_loop._next_delay) with a test on a virtual clock that reproduces the board's 87 % without it. PARTIAL panels present from the display's frame clock after a flush; DIRECT panels present fromflush_is_lastas before. The driver claims refresh and device polling from the App while it runs, so the App's own tick no longer eats LVGL's input events.event_loop(asynchronous=...)is still accepted and ignored.Needs PyDevices/pydevices#101 (the new
multimer,appdevanddisplaydev) on the path. Frame pacing measured against the current driver is in that PR's design doc: 91 frames at 33 ms instead of 75 at 40 ms on the same host, and less CPU on a static screen. The consumers (lvgl-micropython, lvgl-python, lvgl-circuitpython) sync this file with theirscripts/sync_from_lvgl_bindings.shafter the merge.Companions: PyDevices/pydevices-examples#149, PyDevices/micropython-pydevices#24. Draft until the hardware phases are in the ledger.