Debug Builds: the console over Wi-Fi (Debug Console, TCP 2323)

cardputer-adv-debug (-DRORO_DEBUG, version +debug) adds a Debug Console:
after a token line, a client gets the last 6 KB of console output, live
lines (ESP-IDF logs included) and the serial commands. The socket task
only queues lines; the main loop runs them. Release builds compile none
of it. The token lives in ~/.config/roro9stack/debug-token, created by
_docker.sh and passed into the container.

All output now goes through `console`, which never waits for USB: a host
that was attached but not reading stalled the main loop up to 2 s per
line. New commands everywhere: info (slots with their versions from NVS,
since the framework stamps its own into each image), tasks, reboot,
boot other, log level, help. scripts/rdbg.py is the client; flash.sh
--debug builds it; CI builds both variants. ADR 0004.

Verified on the device: USB-flashed, then updated over Wi-Fi to a Debug
Build that confirmed on Probation; both slots hold Debug Builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-04 02:44:14 +02:00
co-authored by Claude Opus 5.5
parent 5b199c2436
commit 0fb7f4e9d5
18 changed files with 828 additions and 97 deletions
+52
View File
@@ -0,0 +1,52 @@
#pragma once
#ifdef RORO_DEBUG
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <deque>
#include <string>
#include "service.h"
#include "services/wifi_service.h"
class NetworkClient;
namespace roro {
// Debug Builds only (ADR 0004): the console over Wi-Fi, on TCP 2323 while Wi-Fi is Connected. A
// client sends the debug token as its first line, then gets the recent console backlog, every new
// console line, and runs the same commands as the serial port. One client at a time.
//
// The socket lives on this Service's own task; commands are handed to the main loop (takeCommand),
// which runs them where touching Apps and Services is safe. Their output reaches the client
// through the console ring like everything else.
class DebugConsole : public Service {
public:
static constexpr uint16_t kPort = 2323;
explicit DebugConsole(WifiService& wifi);
const char* name() const override { return "debug"; }
void start() override;
// The next command line a client sent, for the main loop to run.
bool takeCommand(std::string& line);
bool clientConnected() const { return connected_; }
private:
static void taskEntry(void* self);
void listen();
void serve(::NetworkClient& client);
bool authenticate(::NetworkClient& client);
WifiService& wifi_;
TaskHandle_t task_ = nullptr;
SemaphoreHandle_t lock_;
std::deque<std::string> commands_;
volatile bool connected_ = false;
};
} // namespace roro
#endif