Summary
RTT setup is currently a manual painpoint: users must locate the _SEGGER_RTT control block address, pick the right J-Link probe, and start/drain the buffer by hand. Meanwhile nsx view silently captures nothing for RTT-only apps (e.g. coremark), because nothing declares the app's console transport.
NSX already owns all the data needed to remove this friction (built ELF, SEGGER device/clock config, and --probe-serial plumbing), so RTT can become a first-class console transport that mirrors the existing flash/view model while preserving the ability to "eject" to raw SEGGER/pylink commands.
Motivation
Observed during the AP510 runtime sweep: coremark flashed successfully but nsx view showed no output because its score is emitted over SEGGER RTT (channel 0), not SWO/ITM. See examples/coremark/README.md and the working-but-manual helper examples/coremark/tools/rtt_capture.py, which requires the user to pass a hardcoded --rtt-addr and cannot select a probe serial.
Proposed work
1. nsx rtt command (mirrors nsx view)
- Same app/board selectors and
--probe-serial plumbing already used by view_app (src/neuralspotx/api/_app.py) and the CLI (src/neuralspotx/cli/__init__.py).
- Auto-extract the
_SEGGER_RTT address directly from the built ELF symbol table (no manual hex, no map parsing).
- Start RTT, wait for the up-buffer to come live (race already handled in
examples/coremark/tools/rtt_capture.py), then stream channel 0.
- Support
--out/--file line-streamed capture, matching view --file.
2. Declare console transport in nsx.yml
console:
transport: rtt # or swo (default)
rtt_channel: 0
nsx view on an RTT app prints a friendly redirect to nsx rtt instead of silently capturing nothing.
nsx rtt on a pure-SWO app warns symmetrically.
- Removes README/tribal-knowledge as the only source of transport truth.
3. Preserve the eject path
--print-cmd / --dry-run: emit the fully resolved invocation (device, speed, probe serial, block address) without running.
--print-address: print just the resolved _SEGGER_RTT address (the one annoying-to-find value).
- Generate a committed per-app/board RTT artifact under
build/<board>/jlink/<app>/, mirroring how flash_cmds.jlink / reset_cmds.jlink are generated in src/neuralspotx/cmake/nsx_helpers.cmake.
Rollout order
nsx rtt with auto-address extraction + probe-serial reuse (self-contained, biggest win).
console.transport in nsx.yml + cross-warnings in view/rtt.
- Eject affordances (
--print-cmd, --print-address, generated RTT artifact).
Acceptance criteria
References
examples/coremark/README.md (RTT vs SWO note)
examples/coremark/tools/rtt_capture.py (current manual helper)
src/neuralspotx/cmake/nsx_helpers.cmake (flash/view/reset target generation)
src/neuralspotx/api/_app.py, src/neuralspotx/cli/__init__.py (probe-serial plumbing)
Follow-up PR to implement.
Summary
RTT setup is currently a manual painpoint: users must locate the
_SEGGER_RTTcontrol block address, pick the right J-Link probe, and start/drain the buffer by hand. Meanwhilensx viewsilently captures nothing for RTT-only apps (e.g.coremark), because nothing declares the app's console transport.NSX already owns all the data needed to remove this friction (built ELF, SEGGER device/clock config, and
--probe-serialplumbing), so RTT can become a first-class console transport that mirrors the existingflash/viewmodel while preserving the ability to "eject" to raw SEGGER/pylink commands.Motivation
Observed during the AP510 runtime sweep:
coremarkflashed successfully butnsx viewshowed no output because its score is emitted over SEGGER RTT (channel 0), not SWO/ITM. Seeexamples/coremark/README.mdand the working-but-manual helperexamples/coremark/tools/rtt_capture.py, which requires the user to pass a hardcoded--rtt-addrand cannot select a probe serial.Proposed work
1.
nsx rttcommand (mirrorsnsx view)--probe-serialplumbing already used byview_app(src/neuralspotx/api/_app.py) and the CLI (src/neuralspotx/cli/__init__.py)._SEGGER_RTTaddress directly from the built ELF symbol table (no manual hex, no map parsing).examples/coremark/tools/rtt_capture.py), then stream channel 0.--out/--fileline-streamed capture, matchingview --file.2. Declare console transport in
nsx.ymlnsx viewon an RTT app prints a friendly redirect tonsx rttinstead of silently capturing nothing.nsx rtton a pure-SWO app warns symmetrically.3. Preserve the eject path
--print-cmd/--dry-run: emit the fully resolved invocation (device, speed, probe serial, block address) without running.--print-address: print just the resolved_SEGGER_RTTaddress (the one annoying-to-find value).build/<board>/jlink/<app>/, mirroring howflash_cmds.jlink/reset_cmds.jlinkare generated insrc/neuralspotx/cmake/nsx_helpers.cmake.Rollout order
nsx rttwith auto-address extraction + probe-serial reuse (self-contained, biggest win).console.transportinnsx.yml+ cross-warnings inview/rtt.--print-cmd,--print-address, generated RTT artifact).Acceptance criteria
nsx rtt <app> --board <board> --probe-serial <sn>capturescoremarkoutput on AP510 with no manual address.nsx viewon an RTT-declared app redirects tonsx rttinstead of empty capture.References
examples/coremark/README.md(RTT vs SWO note)examples/coremark/tools/rtt_capture.py(current manual helper)src/neuralspotx/cmake/nsx_helpers.cmake(flash/view/reset target generation)src/neuralspotx/api/_app.py,src/neuralspotx/cli/__init__.py(probe-serial plumbing)Follow-up PR to implement.