Public Access
Shell: the console's commands on the device's own screen and keyboard (#67)
An App in the Launcher that runs the same commands as USB serial and the Debug Console, trusted like the first. It shows what the console prints while it is open, through a second ring of the console's that exists only meanwhile; Ctrl+b keeps only what follows your own commands. Tab completes a command's name from the firmware's help text, Fn with up and down recalls earlier lines, Alt with up and down scrolls back. `rm` asks first in the Shell, `rm -f` doesn't. Nothing is kept once the App is left. `screenshot [seconds]` saves the screen as a PNG in /screenshots on the card, now or after a pause: written a row at a time, indexed colour with RGB332 as the palette, in one stored deflate block. 487 host tests (11 new: the PNG writer, the Shell's log filter, Tab). Checked on the device over the Debug Console: commands, Tab, history, a screenshot fetched and decoded on the PC, rm with and without the question, a delayed screenshot of another screen. 12 KB of flash; 7 KB of heap while open. Decisions Q204 to Q212 in docs/milestones/S1.md. Safe Mode: #77. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -8,6 +8,6 @@ sort_by = "weight"
|
||||
eyebrow = "Developer docs"
|
||||
+++
|
||||
|
||||
The firmware is open source (GPL-3.0) and lives on [Gitea](https://git.twis.la/twisla/roro9stack). It is built for one device, the M5Stack Cardputer ADV with the Cap LoRa-1262, and it is built to be **worked on without touching the device**: install a build over Wi-Fi, read its console, press its keys, take screenshots of it, copy files to and from its SD card, and fetch its crash dumps, all from a PC on the same network. The first section is about exactly that.
|
||||
The firmware is open source (GPL-3.0) and lives on [Gitea](https://git.twis.la/twisla/roro9stack). It is built for one device, the M5Stack Cardputer ADV with the Cap LoRa-1262, and it is built to be **worked on without touching the device**: install a build over Wi-Fi, read its console, press its keys, take screenshots of it, copy files to and from its SD card, and fetch its crash dumps, all from a PC on the same network. The first section is about exactly that. The same commands also run on the device itself, in the [Shell](/guide/shell/).
|
||||
|
||||
Some of these pages are written by hand. The rest are **generated from the repository's own documents** (the decisions, the milestone plans, the README and the firmware's own `help` text), so they are never out of date: each says which file it comes from.
|
||||
|
||||
@@ -19,10 +19,11 @@ net bytes each network service has read and written since boot
|
||||
reboot restart
|
||||
boot other restart into the other app slot (manual Rollback)
|
||||
log level <0-5> ESP-IDF log level (0 none ... 5 verbose)
|
||||
ls [folder] | du <path> | mkdir <path> | rm <path> | cp [-f] <from> <to> | mv [-f] <from> <to> | cancel the SD card, with the Storage App's rules
|
||||
ls [folder] | du <path> | mkdir <path> | rm [-f] <path> | cp [-f] <from> <to> | mv [-f] <from> <to> | cancel the SD card, with the Storage App's rules
|
||||
screenshot [seconds] the screen as a PNG in /screenshots on the card, now or after a pause
|
||||
lora probe | lora status | lora rx on|off | lora preset <name> the LoRa radio, receive only
|
||||
lora capture start|stop a LoRa Capture to /captures/lora (pcap, LoRaTap)
|
||||
lora sweep on [from MHz] [to MHz] [step kHz] | off | dump RSSI across a band (863 870 100)
|
||||
lora sweep on [from MHz] [to MHz] [step kHz] | lora sweep off | lora sweep dump RSSI across a band (863 870 100)
|
||||
lora custom <MHz> <BW kHz> <SF> <CR 5-8> <sync hex> [preamble] e.g. 868.1 125 7 5 34 8 (LoRaWAN)
|
||||
gnss quiet on|off pause the GNSS receiver while the LoRa radio listens (it costs the radio 8 dB)
|
||||
gnss status | gnss restart | gnss track start|stop | gnss nmea on|off | gnss send <sentence without $ and checksum>
|
||||
@@ -35,7 +36,7 @@ wifi dns <a> [b] | wifi dns always on|off | wifi ntp <a> [b] DNS and NTP serve
|
||||
gemini get <url> fetch a Gemini page and report header, size, certificate, heap
|
||||
irc start | irc stop | irc dump | irc say <buffer> <text>
|
||||
install <path.ota> Update from SD
|
||||
update check | list | status | install <tag> the project's releases on Gitea
|
||||
update check | update list | update status | update install <tag> the project's releases on Gitea
|
||||
sd card | sd list | cat <path> | log <text> | burst | sound on|off | short | normal
|
||||
debug status | debug off [seconds] the Debug Console over Wi-Fi (Settings > Debug Console); with seconds, it comes back
|
||||
debug on | debug token <16 to 64 characters> | debug token new (USB serial only) switch it on, set its token
|
||||
@@ -47,7 +48,7 @@ lora inject <hex> [rssi] [snr] a packet into the LoRa Scanner as if received (
|
||||
sd fill <folder> <count> makes that many small files there, to test a crowded folder
|
||||
coredump get (Debug Console only) send the raw core dump: use scripts/rdbg.py coredump
|
||||
reset (Debug Console only) restart at once, even if the main loop is stuck
|
||||
get <path> | put <path> <size> <sha256> | screenshot (Debug Console only) binary, see rdbg.py
|
||||
get <path> | put <path> <size> <sha256> | screenshot (Debug Console only) binary, see rdbg.py: there, a bare `screenshot` sends the screen instead of saving it
|
||||
quit close the Debug Console connection
|
||||
```
|
||||
|
||||
@@ -84,7 +85,8 @@ In **Safe Mode** (see [Crashes and Safe Mode](/dev/debug/crashes/)) only a few r
|
||||
| `reboot` / `boot other` | Restart, or restart into the other app slot (a manual Rollback) |
|
||||
| `log level <0-5>` | ESP-IDF log level |
|
||||
| `ls [folder]` / `du <path>` | Lists a folder of the SD card with sizes and dates, or counts the files and bytes under a path |
|
||||
| `cp [-f] <from> <to>` / `mv [-f] <from> <to>` / `rm <path>` / `mkdir <path>` / `cancel` | What the Storage App does, with its rules: copy (folders too), move or rename, delete (a folder with what's in it), new folder. `-f` replaces a file that's in the way; a tab separates paths that hold spaces; `cancel` stops a copy or a delete |
|
||||
| `screenshot [seconds]` | The screen as a PNG in `/screenshots` on the card, now or after a pause to get to the screen you want (240 x 135, about 33 KB). Over the Debug Console a bare `screenshot` sends the screen to the PC instead |
|
||||
| `cp [-f] <from> <to>` / `mv [-f] <from> <to>` / `rm [-f] <path>` / `mkdir <path>` / `cancel` | What the Storage App does, with its rules: copy (folders too), move or rename, delete (a folder with what's in it), new folder. `-f` replaces a file that's in the way; a tab separates paths that hold spaces; `cancel` stops a copy or a delete |
|
||||
| `install <path>` | Update from SD with that `.ota` file, as Settings → Firmware does |
|
||||
| `update check` / `update list` / `update status` / `update install <tag>` | The project's releases on Gitea: look at the latest, list the last ten, say what's known, or download and install one |
|
||||
| `update pretend <version>` / `update probe <host>` / `update damage cut\|flip <n>` / `update daily` | Pretend to run another version (so a release counts as an update), see whether a server's certificate is accepted, cut or damage the next download, run the daily check again |
|
||||
|
||||
@@ -45,6 +45,7 @@ The device sends `screenshot: rgb332 <width> <height>` and then **one byte per p
|
||||
|
||||
- It is read **as it stands**, while the UI may be drawing, so it can **tear**. It is for looking at, not for pixel-exact comparison.
|
||||
- It is the real thing: the screenshots on this site, in the [user guide](/guide/) and the [devlog](/devlog/), were taken this way.
|
||||
- **With a number, it saves to the card instead:** `screenshot 5` (or `screenshot 0`) writes a PNG to `/screenshots` on the SD card after that many seconds, as the [Shell](/guide/shell/) does. A bare `screenshot` over the console is the binary one above.
|
||||
- Its main use is in a loop: send a key, wait a moment, take a screenshot, look. See [Drive the UI](/dev/debug/drive-the-ui/).
|
||||
|
||||
## `coredump get`: the crash dump
|
||||
|
||||
@@ -144,3 +144,44 @@ M3 found the LoRa radio's noise floor about 15 dB above what the chip hears alon
|
||||
**Settings > Pause GNSS for LoRa**, off by default: while the LoRa radio listens or sweeps, the GNSS receiver waits in standby, and wakes when the radio goes back to sleep (a Fix again after about 7 s here). Never during a Track. The GNSS App says "GNSS is paused" meanwhile. `gnss quiet on|off` on the console.
|
||||
|
||||
It's off by default because GNSS on by default was decided in M2 (Q58), and from M4 the radio listens all the time: then "pause while listening" means GNSS mostly off, which is a decision about position, the clock and Tracks, for M4's design round (issue #23).
|
||||
|
||||
## The Shell (issue #67)
|
||||
|
||||
The console's commands could only be typed on a PC: over USB, or over Wi-Fi with the Debug Console. A device in a bag, or on a network that is down, could not be asked anything. The Shell is an App that runs the same commands on the device's own screen and keyboard.
|
||||
|
||||
### Decisions (design round 2026-10-07)
|
||||
|
||||
| # | Decision |
|
||||
|---|---|
|
||||
| Q204 | **An App, "Shell", in the Launcher**, in every firmware: its commands already work over USB for anyone holding the device. |
|
||||
| Q205 | **Trusted like USB serial**, not like the network: `debug on` and `debug token` work from it, as they do in Settings. The token is never shown. |
|
||||
| Q206 | **It shows what the console prints while it is open**, replies and background alike, without the free-heap line every ten seconds. **Ctrl+b hides the background:** then only what is printed in the ten seconds after a command is kept. A reply can't be told from other output any better: `ls` and `tasks` answer later, from other tasks. |
|
||||
| Q207 | **Nothing while it's closed.** Open, a 4 KB ring of the console's and up to 4 KB of lines; both go when the App is left, with the list of commands for Tab. |
|
||||
| Q208 | Enter runs the line; Fn with up and down recalls the last 16; Alt with up and down scrolls back; **Tab completes the command's first word** from the firmware's `help` text. Paths aren't completed. |
|
||||
| Q209 | **`rm` asks first, `rm -f` doesn't** (in the Shell only: over the consoles, scripts delete as before). **`screenshot [seconds]`** saves the screen as a PNG in `/screenshots`, now or after a pause, since from the Shell "now" is the Shell. `get`, `put`, `coredump get` and `reset` answer `Debug Console only`. |
|
||||
| Q210 | Commands are echoed as `> command` into the console, so a session reads the same from afar. **A token being set is not echoed.** |
|
||||
| Q211 | **Not in Safe Mode**, which starts no Apps: issue #77. |
|
||||
| Q212 | Its keys are a table in `app_keys.h`, so the help panel and the website have them; a page in the user guide. |
|
||||
|
||||
### As built
|
||||
|
||||
- **`ShellApp`** (`src/apps/shell_app.cpp`), with its model host-tested in `lib/apps_model/src/shell_log.h`: lines arriving in pieces, the two filters, the 4 KB limit, the command words out of the `help` text, and Tab (7 tests).
|
||||
- **The console has a second ring** (`Console::openShellRing`), filled like the Debug Console's and independent of it.
|
||||
- **`screenshot`** writes the PNG a row at a time with no buffer: 8-bit indexed colour, the 256 colours of RGB332 as the palette, the pixels in one stored deflate block (`lib/files/src/png_rgb332.h`, 4 tests). 33,383 bytes for the 240 x 135 screen. A Toast says so once it is on the card, so the Toast is never in the picture.
|
||||
- **The `help` text lost its shorthand** (`update check | list | status` is written out), since Tab reads its first words from there.
|
||||
- **Cost:** 12 KB of flash, 16 bytes of static RAM. Open: 7 KB of heap (107.6 KB free before, 100.7 with it open, 106.1 after leaving).
|
||||
|
||||
### Checks on the device (2026-10-07, driven over the Debug Console with `key`)
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| Open it from the Launcher, type `ls /`, Enter | The folders are listed |
|
||||
| Tab on `in` | `info install` is shown and the line stays; on `u` it becomes `update `; on `l`, `log ls lora loop` |
|
||||
| Up | The line before comes back |
|
||||
| `screenshot` | `/screenshots/20261007-104357.png`, 33,383 bytes. Fetched and decoded on the PC: 240 x 135, indexed, every chunk's CRC right, the pixels the Shell's screen |
|
||||
| `rm /shelltest` | Asks. Cancel leaves the folder; Delete removes it. `rm -f` removes without asking |
|
||||
| `screenshot 4`, then Home | The picture, taken four seconds later, is of the Launcher: the pause works, and the Toast isn't in it |
|
||||
| `quit` | Back to the Launcher, and the memory comes back |
|
||||
| The help panel in the Shell | Its keys, then the ones that work everywhere |
|
||||
|
||||
**Not checked:** Ctrl+b and the Alt scroll, which `key` can't press (no modifiers): the filter itself is host-tested, the key that flips it is not; the real keyboard altogether; and the Toast after a screenshot, which was published but not looked at.
|
||||
|
||||
Reference in New Issue
Block a user