|
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 CM55 code produces nothing by default, and how to change that.
Event plane — the packed heartbeat. Inside a set no per-model intent event is sent: the intent byte could report only the set, not the member that fired (read members with ai_engine_snapshot_model()). The 1 s heartbeat sent while a model runs therefore carries packed counters in one 32-bit value:
| Bits | Value | Meaning |
|---|---|---|
| [31:28] | ai_engine_init_calls() & 0xF | 0 = the task never reached the model's init() |
| [27:20] | ai_engine_last_init_rc() & 0xFF | 0 = ok; otherwise the model's failure code |
| [19:16] | ai_engine_feeds() & 0xF | low nibble of the model-intake counter |
| [15:12] | ai_engine_inits() & 0xF | completed cold loads |
| [11:0] | ai_engine_dq_ok() & 0xFFF | verdicts published |
Read the feeds nibble across consecutive beats: 0 on every beat = no new IMU sample reaches the model (the CM33 sensor push is not advancing); non-zero but frozen = the push stopped mid-run; changing with dq_ok climbing = feed and inference healthy, so if result() is still None the break is in the result read path; changing with dq_ok == 0 = samples arrive but no verdict is published, for one of two reasons — the model's window never completes (model, rate or geometry mismatch), or every inference ran past the Ethos-U wait bound and its result was withheld. stale_drops tells those two apart.
Pull plane — MODEL_LINK_Q_DIAG. Answered even while inference is stalled, and surfaced as edge_ai.diag(). Its keys map to the getters in the field guide below.
Screen plane — the stats row. The Edge AI page 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. |
| 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 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(): 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 |