Public Access
Debug Console: files, screenshots and Update from SD over Wi-Fi
New commands everywhere: ls, rm and install <path> (Update from SD without the Firmware page), all as Storage Service jobs. In Debug Builds the console task answers get and put (one storage job per transfer, file kept open, TCP flow control: about 300 KB/s, against 55 KB/s over serial) and screenshot (the RGB332 frame the UI composes into). rdbg.py turns those into files and PNGs. A failed put closes the connection: the rest of the file had been parsed as commands. Card writes are retried 3 times after closing, truncating to the last good byte and reopening, since FATFS keeps a file in error after one failed write (seen once at 1.3 MB on this card). onStorage() decides with one compare-and-swap whether the job or the timeout wins, so an abandoned job can't touch a returned stack frame. Verified on the device: screenshot; a get round trip byte-identical; 4 puts in a row; a tampered .ota refused by install; a good one put, installed from SD, confirmed on Probation. The retry path itself has not fired since it was added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
+24
-2
@@ -144,7 +144,7 @@ void setup() {
|
||||
services.add(*irc);
|
||||
services.add(*update);
|
||||
#ifdef RORO_DEBUG
|
||||
debugConsole = new DebugConsole(*wifi);
|
||||
debugConsole = new DebugConsole(*wifi, *storageService);
|
||||
services.add(*debugConsole);
|
||||
#endif
|
||||
|
||||
@@ -160,6 +160,9 @@ void setup() {
|
||||
bus.subscribe(EventType::Notification, [](const Event& e) { console.printf("notification: %s\n", e.text); });
|
||||
|
||||
if (!screen.begin()) console.println("frame buffer allocation failed");
|
||||
#ifdef RORO_DEBUG
|
||||
debugConsole->setFrame(screen.canvas()); // for `screenshot`
|
||||
#endif
|
||||
services.startAll(millis());
|
||||
apps->begin();
|
||||
if (!settings.getBool(Setting::SetupDone)) apps->openModal("setup");
|
||||
@@ -188,11 +191,14 @@ static void setupSafeMode(int crashes) {
|
||||
services.add(*wifi);
|
||||
services.add(*update);
|
||||
#ifdef RORO_DEBUG
|
||||
debugConsole = new DebugConsole(*wifi);
|
||||
debugConsole = new DebugConsole(*wifi, *storageService);
|
||||
services.add(*debugConsole);
|
||||
#endif
|
||||
bus.subscribe(EventType::Notification, [](const Event& e) { console.printf("notification: %s\n", e.text); });
|
||||
screen.begin();
|
||||
#ifdef RORO_DEBUG
|
||||
debugConsole->setFrame(screen.canvas());
|
||||
#endif
|
||||
services.startAll(millis());
|
||||
console.printf("%s %s in SAFE MODE: %d crash restarts in a row. Only Wi-Fi and Firmware Updates run.\n",
|
||||
kProductName, versionString(), crashes);
|
||||
@@ -322,11 +328,13 @@ static const char* const kHelp =
|
||||
"key <name|char> press a key: up down left right select back home, or one character\n"
|
||||
"wifi status | wifi add <ssid><TAB><password>\n"
|
||||
"irc start | irc dump | irc say <buffer> <text>\n"
|
||||
"ls [folder] | rm <path> | install <path.ota> (Update from SD)\n"
|
||||
"sd list | cat <path> | log <text> | burst | sound on|off | short | normal\n"
|
||||
#ifdef RORO_DEBUG
|
||||
"crash abort|wdt crash on purpose (to test crash reports and Safe Mode)\n"
|
||||
"coredump get (Debug Console only) send the raw core dump: use scripts/rdbg.py coredump\n"
|
||||
"reset (Debug Console only) restart at once, even if the main loop is stuck\n"
|
||||
"get <path> | put <path> <size> <sha256> | screenshot (Debug Console only) binary, see rdbg.py\n"
|
||||
"quit close the Debug Console connection\n"
|
||||
#endif
|
||||
;
|
||||
@@ -362,6 +370,20 @@ static void runCommand(String line) {
|
||||
esp_log_level_set("*", static_cast<esp_log_level_t>(constrain(level, 0, 5)));
|
||||
console.printf("log level: %d\n", constrain(level, 0, 5));
|
||||
}
|
||||
if (line == "ls" || line.startsWith("ls ") || line.startsWith("rm ")) {
|
||||
if (!storageService->state().present) return (void)console.println("sd: no card");
|
||||
bool list = !line.startsWith("rm ");
|
||||
std::string path = line.length() > 3 ? line.substring(3).c_str() : "/";
|
||||
storageService->runJob([list, path]() { // card access stays on the storage task
|
||||
if (!list) return (void)console.printf("rm: %s %s\n", path.c_str(), SD.remove(path.c_str()) ? "removed" : "failed");
|
||||
File dir = SD.open(path.c_str());
|
||||
if (!dir || !dir.isDirectory()) return (void)console.printf("ls: %s is not a folder\n", path.c_str());
|
||||
for (File f = dir.openNextFile(); f; f = dir.openNextFile())
|
||||
console.printf("%10u %s%s\n", f.isDirectory() ? 0u : (unsigned)f.size(), f.name(), f.isDirectory() ? "/" : "");
|
||||
console.printf("ls: end of %s\n", path.c_str());
|
||||
});
|
||||
}
|
||||
if (line.startsWith("install ")) update->installFromSd(line.substring(8).c_str()); // Update from SD
|
||||
if (line == "crash") crash_report::print(console, nvs);
|
||||
if (line == "coredump erase") console.println(crash_report::erase() ? "coredump: erased" : "coredump: nothing to erase");
|
||||
#ifdef RORO_DEBUG
|
||||
|
||||
Reference in New Issue
Block a user