You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Arduino: correct the link mode guidance and pin the board core in CI
Two users hit the same wall within an hour of the library reaching Library
Manager: install it, open an example, Verify, and get
Sketch too big; text section exceeds available space
The README described Dynamic link mode as producing "no serial output at all,
so the board looks dead", which is wrong -- it fails at compile time, so a
user searching for the error they actually saw found nothing. Corrected, and
moved up into the error table with the real message.
Why it happens, since the README had no explanation: Dynamic does a relocatable
link (-r). --gc-sections is passed in both modes but can only work in a final
link, where the linker has an entry point to trace reachability from. Under -r
nothing can be proven unreachable, so every vendored operator survives, and
because a loadable extension is loaded into RAM the retained code is charged
against RAM too. AddModel on core 0.90.0: 507,876 bytes static, 787,508 dynamic.
Recorded that the library cannot work around this. Trimming the vendored
operator sources to only the registered set -- 15 instead of 172 -- moved the
dynamic build 852 bytes. The bulk is the runtime, flatbuffers and CMSIS-NN.
Memory figures were measured on core 0.55.2, which reported a 131,072-byte RAM
ceiling; 0.90.0 reports 262,144, so they were not comparable to anything a
current user sees. Re-measured all three examples on 0.90.0. The KeywordSpotting
arena band is now scoped to the core it was measured on, with the upper bound
marked untested on 0.90.0 -- 40 KB is confirmed, above that is not.
CI pins arduino:zephyr@0.90.0 and Arduino_RouterBridge@0.4.3 rather than
resolving to latest, so a failure means a real incompatibility instead of an
upstream release landing under us. The core moved 0.55.2 -> 0.90.0 unannounced
during this work. Adds the retry and network.connection_timeout hardening the
~1 GB toolchain download needs, since that toolchain is a ~1 GB GitHub release
asset that outruns arduino-cli's default HTTP timeout.
Bumps library.properties to version 0.1.1.
Tracking of dynamic-mode sizes belongs in meta-pytorch/executorch-arduino, on a
nightly, rather than here: it is a property of the published artifact, and three
extra compiles per pull request touching runtime/ or kernels/portable/ is a poor
trade for telemetry this repo cannot act on.
Authored with assistance from Claude Code.
Copy file name to clipboardExpand all lines: examples/arduino/README.md
+61-31Lines changed: 61 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -247,11 +247,14 @@ A mismatch there is the bug, found in seconds instead of hours.
247
247
248
248
### Things that are not obvious
249
249
250
-
-**`link_mode=static` is mandatory.** The Uno Q defaults to Dynamic, which
251
-
builds the sketch as a Zephyr loadable extension. A library this size never
252
-
starts that way: no serial output at all, so the board looks dead and offers
253
-
nothing to diagnose. Dynamic also reports only the extension's size, roughly
254
-
half the real figure.
250
+
-**`link_mode=static` is mandatory, and Dynamic is the default.** In the IDE
251
+
that is `Tools > Link mode > Static`, which is per-sketch and resets every
252
+
time you open another example. Dynamic does a relocatable link (`-r`), which
253
+
makes `--gc-sections` inert: nothing unused is stripped, so every vendored
254
+
operator survives and the build overflows flash with
255
+
`Sketch too big; text section exceeds available space`. Same sketch, core
256
+
0.90.0: 507,876 bytes on Static, 787,508 on Dynamic. It fails at compile
257
+
time, so there is nothing to see on the serial port either way.
255
258
-**`ET_LOG` has to be routed somewhere.**`zephyr.cpp` logs through `fprintf`,
256
259
and `platform_stubs.c` stubs `fprintf` out. The build script rewrites the
257
260
logger to call a weak `et_arduino_log` hook, which the examples implement
@@ -266,7 +269,8 @@ A mismatch there is the bug, found in seconds instead of hours.
266
269
267
270
| Symptom | Cause |
268
271
|---|---|
269
-
| No serial output at all | Built in Dynamic link mode, or `Arduino_RouterBridge` missing |
272
+
|`Sketch too big; text section exceeds available space`| Built in Dynamic link mode. Set `Tools > Link mode > Static`, per sketch |
273
+
| No serial output at all |`Arduino_RouterBridge` missing, or the monitor attached after `setup()` had already printed |
270
274
|`Program::load` -> `0x23`| Model header put the array in a section the linker discards; use `pte_to_header.py` from this directory, not the Ethos-U one |
271
275
|`load_method` -> `0x14`| Operator not in the registered set; regenerate with `ROOT_OPS=`|
272
276
|`load_method` -> `0x21`|`method_pool` too small; the log line gives the exact shortfall |
@@ -474,38 +478,64 @@ currently supports (`architectures=zephyr`). Other Arduino cores do not run
474
478
Zephyr and have no link mode setting; they need a platform abstraction layer
475
479
port before they can compile at all, and their memory behaviour is untested.
476
480
477
-
On the Zephyr core, the Uno Q defaults to Dynamic link mode, which builds the
478
-
sketch as a Zephyr loadable extension. Sketches this size never start that way: no serial output
479
-
at all, so the board looks dead and offers nothing to diagnose. Build with
480
-
`link_mode=static`. A 2 KB sketch runs fine under Dynamic, so the ceiling sits
481
-
somewhere between that and these builds; it has not been pinned down.
481
+
On the Zephyr core the Uno Q defaults to **Dynamic**, and every example fails to
482
+
build that way. In the IDE, set `Tools > Link mode > Static`. It is a per-sketch
483
+
setting: opening another example puts it back to Dynamic.
482
484
483
-
Dynamic also reports only the extension's own size, which reads far lower than
484
-
what the board actually holds. Measured on an Arduino Uno Q, board core 0.55.2,
485
-
against 786,432 bytes of flash and 131,072 bytes of RAM:
485
+
Dynamic builds the sketch as a Zephyr loadable extension via a relocatable link
486
+
(`-r`). `--gc-sections` is passed in both modes but can only work in a final
487
+
link, where the linker has an entry point to trace reachability from. Under `-r`
488
+
there is nothing to trace from and the output will be linked again later, so
489
+
every section has to be kept. Nothing unused is stripped, and because a loadable
490
+
extension is loaded into RAM, the retained code is charged against RAM as well
0 commit comments