|
SDK for TESAIoT Dev Kit
API reference & tutorials (ModusToolbox)
|
The screen diagnostics row is common to both variants. edge_ai.diag() and ui._diag() are MicroPython REPL calls and exist on mtb-mpy only; the mtb-only equivalent is the screen row plus a C-side call to ipc_ui_platform_diag().
Read the three diagnostic surfaces — the packed heartbeat word, the on-screen stats row, and the edge_ai.diag() dictionary — and apply the one pass condition that matters: npu_cycles advancing while stale_drops stays flat. You will also learn why printf in your own CM55 code produces nothing.
Event plane — the packed heartbeat. Inside a set the intent-event branch is skipped entirely (deepcraft_task.c:831-836, :853-866: every member writes the same slot and the intent byte cannot say which model fired), so the heartbeat carries packed counters instead:
Pull plane — MODEL_LINK_Q_DIAG. Answered in the IPC callback (deepcraft_task.c:356-395) so it still arrives when ai_task is wedged; surfaced as edge_ai.diag() (modedgeai.c:438-489). The getters it reads:
Screen plane — the stats row. page_edge_ai.c:1455-1479 renders push/s feed/s flush/s … init N/M rc R stale S:
Feed rate is a delta over at least one second:
| Field | Getter | How to read it |
|---|---|---|
| npu_cycles | ai_engine_npu_cycles() | u64 split hi/lo over the wire. Advancing = the NPU is being driven. Not proof an inference completed. |
| stale_drops | ai_engine_stale_drops() | Must stay flat while npu_cycles advances — the pass condition. ml_state alone is untrustworthy (modedgeai.c:432-437). |
| feeds | ai_engine_feeds() | Only the diag "feed" field reports model intake. Derive Hz over ≥1 s. |
| dq_ok / dq_calls | ai_engine_dq_ok() / ai_engine_dq_calls() | dq_ok frozen while dq_calls climbs = NPU stall. dq_calls has no shipped caller — authored pairing below. |
| init_calls / init_returns | ai_engine_init_calls() / ai_engine_init_returns() | Read together. "2/1" = entered init and never left. |
| last_init_rc | ai_engine_last_init_rc() | 0x7FFFFFFF = never called; 0 = ok. |
| inits | ai_engine_inits() | Packed nibble in the heartbeat word. |
| stack_words / stack_free_words | ai_engine_stack_words() / ai_engine_stack_free_words() | 0 words = engine never started. stack_free_words is an O(stack) scan — ~1 Hz, never per frame. |
The authored dq_calls pairing:
Select any model on the Edge AI page and wait for CHIP_RUNNING.
What you should observe. The stats row updates about once per second. feed/s is non-zero, the init N/M pair has N == M, rc 0, and stale holds a constant value while the model runs.
What you should observe. (True, True). Any other combination is a stall or a starved feed; see the field guide.
mtb-mpy:
What you should observe. The ten words returned by ipc_ui_platform_diag() (tesaiot_display.c:593-609): DC IRQ status, flush counters (flush_start_count incrementing = frames are flowing), GFX stack HWM, idle %. ui._diag() is modui.c:1470.
mtb-only: there is no REPL. Call ipc_ui_platform_diag(out, max_words) from your own CM55 code with max_words >= 10; it returns 10 words. That accessor — not the g_tesaiot_display_diag struct — is the supported path.
What you should observe. On mtb-mpy the console shows [MPY] at boot and nothing per inference; on mtb-only it shows [HB] t=lus tasks=u every 10 s and nothing else. Do not wait for an Edge AI line — none exists. CM55 does not own a UART (proj_cm55/main.c:9-10).
| mtb-mpy | mtb-only | |
|---|---|---|
| Engine diag | edge_ai.diag() + screen row | Screen row; C-side getters from your own CM55 code |
| GFX diag | ui._diag() | C-side ipc_ui_platform_diag() |
| Console | [MPY] only | [HB] only |