/dev/ has Debug Builds and the Debug Console (builds and the token, the console and its protocol, files and screenshots, driving the UI, crashes and Safe Mode, the command reference), Build, test and release (including how an update works), the architecture decisions and the milestone plans. Generated from the repository by site/tools/gen_dev_docs.py: the ADRs, the milestones, the README's sections, and the command reference, read from the firmware's own `help` text. The pages are committed (Zola cannot read outside its folder); the Site workflow checks they are current, and now also runs when src/main.cpp changes. M0, M1 and CONTEXT.md are not published. README: the gnss commands that the table lacked. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
4.1 KiB
+++ title = "Debug Builds" description = "What a Debug Build is, how to build and flash one, how its token works, and why you should keep one in the fallback slot." weight = 1 [extra] tag = "Start here" +++
What it is
A Debug Build is built from the same source as a release, with the cardputer-adv-debug environment (it extends cardputer-adv in platformio.ini) and -DRORO_DEBUG. Differences:
- the Debug Console on TCP 2323 (next page);
- extra commands, only meant for testing: crash on purpose, fake an installed version, damage a download, inject a LoRa packet, fill a folder with files (see the command reference);
- the version ends in
+debug(scripts/version.py) wherever the version shows: Settings,info, the Update Service. A+debugversion compares equal to its release counterpart, so going between the two is never refused as a downgrade.
It is compiled out of release builds, not switched off by a setting. A console that runs commands, presses keys and reboots the device is a remote control; in a release build nothing listens and the code is not there.
Build and flash one
Everything runs in Docker (see Build, test and release). Over USB:
scripts/flash.sh --debug # builds cardputer-adv-debug, uploads, opens the serial monitor
Once a Debug Build is on the device, every later one can go over Wi-Fi, with no cable:
export RORO_OTA_HOST=10.39.39.12 # the address Settings > Firmware shows
scripts/flash.sh --debug --ota # builds, signs and pushes; the device installs and restarts
The device's address is on Settings → Firmware ("Push to", which also gives port 3232, the update port). The Debug Console is on the same address, port 2323. See Flash and update for the update side.
The token
The console asks for a secret first. It is 128 random bits, made the first time any build runs (scripts/_docker.sh), kept in ~/.config/roro9stack/debug-token next to the update-signing key, and passed into the build container as RORO_DEBUG_TOKEN. scripts/debug_flags.py compiles it into the firmware, and refuses to build a Debug Build without one, rather than fall back on a default.
- It is never committed. Releases have no console, so nothing of it is published: CI builds a Debug Build on a pull request to prove it still compiles, but never publishes it, because each one carries its builder's token.
- It guards against the network, not against someone who holds the device: anyone with USB access can flash anything anyway (ADR 0003).
- To change it, delete the file and build again; the new token goes into the next Debug Build you flash.
Keep a Debug Build in the other slot
The device has two app slots, so an update never overwrites the running firmware. If a new firmware crashes during Probation, the device goes back to the previous one, whatever that is. As long as you develop on Debug Builds, the firmware a crash falls back to has the console too, so a bad update never costs you remote access. Pushing a release build over a Debug Build leaves the Debug Build in the other slot until the next update overwrites it.
So the habit is: develop on Debug Builds, release by tag, and think twice before pushing a release over the only Debug Build you have.
Releases and Debug Builds
- A Debug Build shows the latest release in Settings → Firmware but never installs it: that would replace the console with a release that has none. Update a Debug Build from the PC with
scripts/flash.sh --debug --ota. - A Debug Build still checks and lists releases, which is useful for testing the update path:
update pretendmakes a released version count as newer (see Drive the UI). - Safe Mode (after 3 crashes in a row) keeps the Debug Console running, so a crash loop is something you fix remotely: see Crashes and Safe Mode.
The reasoning is in ADR 0004.