|
SDK for TESAIoT Dev Kit
API reference & tutorials (ModusToolbox)
|
The CM55 handler mechanics apply to both variants. The drive side of this chapter — the ui.* MicroPython module and ui._diag() — is mtb-mpy only; on mtb-only the same handler exists but nothing in the shipped firmware sends it commands.
Understand that the 25 ui_widget_mgr_* functions are not a C API for your page code. Their sole caller is the IPC_UI command switch inside the ipc_core archive; the real clients are MicroPython scripts crossing IPC. After this chapter you can trace a ui.Label(...) call from the REPL to an LVGL object, and you know which seven symbols you implement rather than call.
The contract in one line — ipc_ui.h:7-8: the ISR half only enqueues; LVGL work happens on the 50 ms timer in GFX-task context. Header contract ui_widget_mgr.h:6: "Creates, modifies, deletes LVGL widgets in GFX task context".
Init. ipc_ui_init(NULL) is called last in CM55 bring-up and gated on display_ok; it calls ui_widget_mgr_init() itself — never call that yourself. Both containers take NULL (deferred binding).
Bind on page create, NULL on destroy. The Playground page is the shipped exemplar:
Dispatch. The UI command dispatch inside the archive (drained from the 50 ms LVGL timer) is a switch over IPC_CMD_UI_* (ipc_ui_protocol.h); 22 of the 25 primitives dispatch inside it. Each case unpacks the message and calls one primitive.
Event drain — the producer is ui_widget_mgr_event_push (behind the per-widget event mask), the consumer is the POLL_EVENTS case.
Two primitives do not dispatch from the switch: ui_widget_mgr_init (inside ipc_ui_init) and ui_widget_mgr_set_parent (sole caller ipc_ui_set_container()). One, ui_widget_mgr_count, has no caller anywhere and is authored.
The parent is nullable. Every one of five call sites null-checks it — it is NULL between set_container(NULL) on destroy and the next page's bind.
Home → Playground.
What you should observe. A console panel. Console and widget layer are mutually exclusive; the toggle is a blind toggle, always guarded by ipc_lcd_is_panel_visible():
What you should observe. The widget container un-hides on the first POLL_EVENTS and the label appears; text() updates it within a 50 ms tick (SET_TEXT also arms fast mode). Label strings are cut at 95 bytes in the constructor: UI_CREATE_TEXT_MAX is 96 (ipc_ui_protocol.h:658) and the constructor truncates to UI_CREATE_TEXT_MAX - 1 (modui.c:1223).
What you should observe. The ten words from ipc_ui_platform_diag(); flush_start_count increments between two calls. On mtb-only, call ipc_ui_platform_diag(out, 10) from your own CM55 code instead.
The Playground restart tears widgets down before the IPC restart command, so CM33_NS cannot push into a half-cleared table:
What you should observe. Widgets vanish, then the script's widgets re-appear. The CLEAR_ALL command also resets LCD auto-navigation (ipc_lcd_reset_auto_nav(), ipc_lcd.h).
Exactly the dist/ipc_core/overridable.txt list: cm55_controls_snapshot (template override cm55_sensor_poll.c:387), game_sprite_create / game_sprite_set (game_sprite_engine.c:16/:25), game_sprite_lookup (game_sprite_registry.c:52), ipc_ui_ext_dispatch (ipc_ui_ext_chain.c:41, runs in GFX context and may touch the display, ipc_ui.h:40-41), ipc_ui_ext_clear_all (W in the archive), ipc_ui_platform_diag (strong def archived in libbento_cm55.a). A reference page that says "call this" for any of them is wrong.
| mtb-mpy | mtb-only | |
|---|---|---|
| Drive side | ui.* module over IPC | No shipped sender; handler present |
| Frame proof | ui._diag() | C-side ipc_ui_platform_diag() |
| Page mechanics | identical | identical |