Serial console
The badge exposes a line-oriented command console over its USB CDC serial port. It is the primary way to inspect device state, manage stored secrets, drive the plugin and file-system shells, and reflash the firmware without touching the hardware buttons.
This page covers connecting, the authentication model, and a practical orientation. For the full per-command table see the serial command reference.
Connecting
Section titled “Connecting”- Plug the badge into a USB port. It enumerates as a USB CDC device.
- Open the port at 115200 baud with any serial terminal.
- On connect the badge prints a banner:
=== CDC Badge OS Serial Console ===Login with: AUTH <pin>Type 'HELP' for available commands.The Login with: AUTH <pin> line only appears in builds where secure serial is
enabled (off by default, see below). Press Enter or type HELP to confirm the
console is live.
On macOS the badge appears as /dev/cu.usbmodem*; on Linux as /dev/ttyACM*.
You can drive the console non-interactively, for example:
echo "PING" > /dev/ttyACM0 # expect: PONGLine editing
Section titled “Line editing”The console supports basic line editing:
| Key | Action |
|---|---|
| Up / Down | Walk command history (last 10 lines) |
| Backspace | Delete the previous character |
| Ctrl+C | Cancel the current line |
| Ctrl+U | Clear the current line |
UTF-8 input (for example umlauts in a display name) is accepted and converted to the badge’s internal CP437 encoding as you type.
The AUTH model
Section titled “The AUTH model”Whether a command needs authentication depends on a build flag and a per-command flag.
Secure serial (off by default)
Section titled “Secure serial (off by default)”FEATURE_SECURE_SERIAL defaults to 0 (off); it is enabled only when the
Kconfig option CONFIG_SECURE_SERIAL is set (see
ADR-0012). With it on, every
command except PING and AUTH is rejected until you authenticate:
> STATUSERROR: Not authenticated. Use AUTH <pin> to login.> AUTH 0000OK: Authenticated> STATUS=== System Status ===...AUTH <pin> uses the badge PIN (the same PIN as the lock screen). After a
successful login the session stays authenticated until it is idle for
5 minutes, after which it times out and you must log in again. Each accepted
command resets the idle timer.
AUTHwith no argument logs you out (or prints usage if you were not logged in).LOGOUTends the session explicitly.- A wrong PIN drops any active session, so the next command runs unprivileged instead of inheriting the old one.
In release builds, verbose INFO/DEBUG log output is also suppressed until a
session is authenticated; errors and warnings keep flowing so boot problems stay
visible.
Per-command authentication
Section titled “Per-command authentication”Some commands carry their own requiresAuth flag, so they need a logged-in
session even in builds where secure serial is disabled. These are the
commands that mutate persistent state or touch secret material, for example
REBOOT, BOOTLOADER, the whole NVS, PIN, TR01, WIFI, MODULE,
BACKUP, GPG, TOTP, PASSWORD, VFAT, PLUGIN and LANG groups.
The auth check is applied at the group level. That means even a read-only
subcommand such as NVS LIST or TR01 STATUS requires authentication, because
its parent command is gated. The only consistently open commands are the
diagnostics listed below plus the time/display setters.
Commands that do not require authentication: HELP, PING, STATUS,
MEM, MEMINFO, CPU, ERROR_LOG, GET_TIME, GET_DATE, SET_TIME,
SET_DATE, SET_NAME, SET_INFO, SET_INFO2, and the VCARD group. In a
build with secure serial enabled these still require a prior AUTH, except
PING.
Discovering commands
Section titled “Discovering commands”HELP prints every registered command grouped by module, including the
subcommands of grouped commands such as NVS, TR01 or PLUGIN:
> HELP=== Available Commands ===
[system] HELP Show available commands PING Check if device is responsive ...Grouped commands use <GROUP> <SUBCOMMAND> [args] syntax. Typing the bare group
name, <GROUP> HELP, or <GROUP> ? prints just that group’s subcommand list:
> NVSUsage: NVS <subcommand> [args]Subcommands: LIST [namespace] List entries (optional namespace filter) READ <ns> <key> Read key value ...A practical orientation
Section titled “A practical orientation”A few things you will reach for often:
- Liveness check:
PINGreturnsPONG. It is the one command that always works, even during a PIN lockout. - System state:
STATUSshows free heap and uptime.MEMandMEMINFOgive heap/PSRAM detail;CPUmeasures aggregate load over about 250 ms. - Reflash without buttons: authenticate, then
BOOTLOADERreboots into USB download mode so you can flash. After flashing, the chip reboots back into the new firmware automatically. See First flash for the full procedure. - Restart:
REBOOTrestarts the device (requires auth). - Clock:
SET_TIME HH:MM:SSandSET_DATE DD.MM.YYYYset the clock;SET_DATEalso accepts a Unix timestamp, for exampleecho "SET_DATE $(date +%s)" > /dev/ttyACM0. - Inspect storage:
NVS LISTwalks the non-volatile key/value store;TR01 SLOTSsummarises secure-element slot usage. - Danger zone: destructive commands require an explicit confirmation token,
for example
NVS CLEAR YESandTR01 WIPE CONFIRM. ThePIN DURESScommand arms a self-destruct PIN. Treat these with care.
Binary uploads
Section titled “Binary uploads”A few commands (the PLUGIN UPLOAD* family and VFAT RECEIVE) switch the
console into a raw byte-streaming mode: the badge replies READY, then consumes
exactly the announced number of bytes from the serial stream and verifies a
CRC-32 before committing the file. While streaming, normal line parsing is
bypassed. Use the supplied tooling (for example tools/upload.py) rather than
pasting binary by hand.
Next steps
Section titled “Next steps”- Serial command reference - the complete, source-verified command table.
- First flash - reflash via the
BOOTLOADERcommand.