SDK for TESAIoT Dev Kit
API reference & tutorials (ModusToolbox)
Loading...
Searching...
No Matches
printf/puts link hazard

dist/edge_ai/api.txt lists 39 exported symbols. Two of them — printf and puts — are not API, not extraction noise, and must never be called on purpose. They are documented here because linking the archive changes the behaviour of your own code.

Variant
mtb-mpy and mtb-only

printf

int printf(const char *fmt, ...); /* defined in the archive as a no-op */

Contract — the hazard. libbento_edge_ai.a defines printf as a deliberate no-op stub (ai_engine.c:276-288: (void)fmt; return 0;). nm -S on the archive reports an 8-byte T printf in bento_core_0.o — the stub, not newlib. Consequences for a CM55 consumer:

  • Any printf in your own CM55 code silently produces nothing once this archive is linked. No warning, no output, no error — the call succeeds and returns 0.
  • You cannot link newlib's stdio into this core. CM55 has no retarget-io; CM33_NS owns the UART (proj_cm55/main.c:9-10). Newlib stdio on CM55 would take a foreign lock and panic (ai_engine.c:270-275), which is exactly why the archive intercepts every stray printf from the vendored ML middleware and TFLite-Micro.
  • CM55 observables are therefore LED codes and the screen on both variants, plus ui._diag() on mtb-mpy (ipc_ui_platform_diag() from C on mtb-only) — never the serial console.

    dist/edge_ai/include/bento_secure_undeclared.h:10-11 records the symbol as "exported, but no declaration found in the tree": no shipped header declares it, because nothing is meant to call it.

puts

int puts(const char *s); /* defined in the archive as a no-op */

Contract — the hazard. Same as printf: a 4-byte no-op T puts (ai_engine.c:283-288) that swallows every puts in the CM55 image, including the ones the compiler synthesises from a printf("literal\n"). Do not rely on either for CM55 output; route diagnostics through the IPC platform-diag path instead.