Files
roro9stack/src/apps/system_app.h
T
twislaandClaude Opus 5.5 e36aa50922 S1 #11: the System App: tasks, memory, network and system, live
Five views, Tab between them: Overview (each core's load, memory,
traffic, battery, two minutes of load), Tasks (share of a core over the
last second, lowest free stack, flagged under 512 bytes; `s` sorts),
Memory (free heap against the floors of Q86), Network (bytes per
service, and what's moving now), System (what `info` prints, plus
battery, card, radio, GNSS). It samples once a second and keeps history
only while open.

The arithmetic is host-tested, including the trap found on the device: a
task's run-time counter only moves when it's switched out, so the task
that samples (the main loop, alone on its core) gets what's left of its
core. `tasks` now samples across a second of normal running instead of
inside its own wait. The main loop uses 100 % of core 1 at rest (#40).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
2026-10-06 01:28:26 +02:00

68 lines
2.3 KiB
C++

#pragma once
#include <string>
#include <vector>
#include "app.h"
#include "key_value_store.h"
#include "services/battery_service.h"
#include "services/gnss_service.h"
#include "services/radio_service.h"
#include "services/storage_service.h"
#include "services/wifi_service.h"
#include "task_stats.h"
#include "traffic.h"
namespace roro {
// The System App (docs/milestones/S1.md, Q117 to Q127): what the device is doing, live and
// read-only. Tab moves between Overview, Tasks, Memory, Network and System. It samples once a
// second and keeps two minutes of history, only while it's open (Q120).
class SystemApp : public App {
public:
SystemApp(WifiService& wifi, BatteryService& battery, StorageService& storage, RadioService& radio, GnssService& gnss,
KeyValueStore& store)
: wifi_(wifi), battery_(battery), storage_(storage), radio_(radio), gnss_(gnss), store_(store) {}
void onEnter() override;
void onExit() override;
bool onKey(const KeyEvent& e) override;
void update(uint32_t nowMs) override;
void draw(Canvas& c) override;
private:
enum class View : uint8_t { Overview, Tasks, Memory, Network, System, Count };
static constexpr size_t kHistory = 120; // seconds
static constexpr int kTaskRows = 7;
void sample(uint32_t nowMs);
void drawOverview(Canvas& c);
void drawTasks(Canvas& c);
void drawMemory(Canvas& c);
void drawNetwork(Canvas& c);
void drawSystem(Canvas& c);
void footer(Canvas& c, const char* keys);
WifiService& wifi_;
BatteryService& battery_;
StorageService& storage_;
RadioService& radio_;
GnssService& gnss_;
KeyValueStore& store_;
View view_ = View::Overview;
uint32_t sampledMs_ = 0;
std::vector<TaskSample> before_;
uint32_t beforeTotal_ = 0;
std::vector<TaskRow> rows_; // the last second, sorted
TaskSort sort_ = TaskSort::Share;
int taskTop_ = 0;
int load_[2] = {-1, -1};
History<uint8_t, kHistory> loadHistory_[2];
History<uint16_t, kHistory> heapHistory_; // free heap, KB
net::Traffic traffic_[static_cast<size_t>(net::User::Count)];
uint32_t rateIn_[static_cast<size_t>(net::User::Count)] = {}, rateOut_[static_cast<size_t>(net::User::Count)] = {};
std::vector<std::string> systemLines_;
int systemTop_ = 0, wrappedLines_ = 0;
};
} // namespace roro