Public Access
The Shell shows the replies to its own commands and nothing else. The console knows who each line is printed for (Console::As, Console::origin): a command run from the Shell prints as the Shell's, and what answers it later from another task carries that along (ls, tasks, du, cp, update check, sd list, screenshot, gemini get). Ctrl+b shows everything instead. This replaces the ten-second window, which was a guess. An App's name with a capital opens it (Notes, Irc, Wifi, Gnss, Gemini, Lora, Storage, Shell, System, Settings), from the Shell and from the consoles. rm needs -r for a folder, here and over the consoles. In the Shell a file, or a folder with something in it, is asked about unless -f; an empty folder with -r goes without a word. The Shell now hands its line to the main loop to run: run from inside the key handler, rm on a folder overflowed the loop's stack and crashed the device. `info` says which App is in front. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
74 lines
3.0 KiB
C++
74 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <Print.h>
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
|
|
namespace roro {
|
|
|
|
// Where the firmware's console output goes: the USB serial port, and while the Debug Console is
|
|
// switched on (ADR 0010) also a ring buffer it sends over Wi-Fi, with what came before the connection.
|
|
// Use `console` instead of Serial for anything a human should be able to read remotely.
|
|
class Console : public Print {
|
|
public:
|
|
size_t write(uint8_t c) override { return write(&c, 1); }
|
|
size_t write(const uint8_t* data, size_t len) override;
|
|
using Print::write;
|
|
|
|
static constexpr size_t kRingBytes = 4096;
|
|
|
|
// The ring exists only while the Debug Console is on: 4 KB of heap a device that never uses it
|
|
// keeps. False if there's no memory for it.
|
|
bool openRing();
|
|
void closeRing();
|
|
bool ringOpen() const { return ring_ != nullptr; }
|
|
|
|
// Also copies ESP-IDF's own log lines into the ring (they still reach the serial port).
|
|
void captureEspLogs();
|
|
// Copies bytes written since `pos` into `out`, and advances `pos`. A reader that fell more than
|
|
// the ring behind gets the oldest bytes still there, and `skipped` says how many it missed.
|
|
size_t readSince(uint32_t& pos, uint8_t* out, size_t max, uint32_t& skipped);
|
|
// The position of the oldest byte still in the ring: a new reader starts there.
|
|
uint32_t oldest() const;
|
|
// The ring only, for output that already reaches the serial port another way.
|
|
void toRing(const uint8_t* data, size_t len);
|
|
|
|
// Who asked for what is being printed. A command typed in the Shell App prints its reply `As`
|
|
// the Shell, and so does whatever answers it later from another task (a listing read by the
|
|
// storage task, `tasks` a second on): the one that starts the work notes origin() and the one that
|
|
// prints takes it back. Everything else is the System's: logs, and the consoles' own commands.
|
|
enum class Origin : uint8_t { System, Shell };
|
|
Origin origin() const; // of the task that asks, now
|
|
class As {
|
|
public:
|
|
explicit As(Origin origin);
|
|
~As();
|
|
As(const As&) = delete;
|
|
As& operator=(const As&) = delete;
|
|
|
|
private:
|
|
bool entered_;
|
|
};
|
|
|
|
// A second ring of the same kind, for the Shell App (issue #67): open while the App is. It gets
|
|
// what is printed As the Shell, and nothing else, so that the Shell shows the replies to its own
|
|
// commands and not the rest (Q206); or everything, when asked.
|
|
bool openShellRing();
|
|
void closeShellRing();
|
|
void shellShowsAll(bool all) { shellAll_ = all; }
|
|
bool shellShowsAll() const { return shellAll_; }
|
|
size_t readShellSince(uint32_t& pos, uint8_t* out, size_t max, uint32_t& skipped);
|
|
|
|
private:
|
|
uint8_t* ring_ = nullptr;
|
|
uint32_t head_ = 0; // total bytes written since the ring opened; it holds the last kRingBytes of them
|
|
uint8_t* shellRing_ = nullptr;
|
|
uint32_t shellHead_ = 0;
|
|
volatile bool shellAll_ = false;
|
|
};
|
|
|
|
extern Console console;
|
|
|
|
} // namespace roro
|