Public Access
The main loop rests between passes (#40)
It made 50,000 passes a second and kept core 1 100 % busy at rest. Keys are buffered by the keyboard controller, the consoles and the radio have their own tasks, and no Service ticks more often than every 50 ms, so the loop now rests 5 ms after a pass with the screen on and 20 ms with it off; never during a serial file transfer. Safe Mode's loop too. Screen off: 50 passes a second and core 1 at 1 %; screen on: 167 and 10 %. The chip settles 4 C cooler (34.3 against 38.3). GNSS, Gemini, an upload, the Sweep and the radio's interrupt all checked at the new pace. `tasks` shows the loop's passes; Debug Builds: `loop spin on|off`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
+38
-1
@@ -390,10 +390,17 @@ static std::vector<TaskSample> tasksBefore;
|
||||
static uint32_t tasksTotal = 0, tasksDueMs = 0;
|
||||
static bool tasksPending = false;
|
||||
|
||||
static uint32_t loopPasses = 0; // counted in loop(), for `tasks` (issue #40)
|
||||
#ifdef RORO_DEBUG
|
||||
static bool loopSpin = false; // `loop spin on`: no rest between passes, to compare load and radio noise
|
||||
#endif
|
||||
static uint32_t tasksPasses = 0;
|
||||
|
||||
static void tasksStep() {
|
||||
if (!tasksPending || static_cast<int32_t>(millis() - tasksDueMs) < 0) return;
|
||||
tasksPending = false;
|
||||
system_info::printTasks(console, tasksBefore, tasksTotal);
|
||||
console.printf("loop: %lu passes in the last second, chip %.1f C\n", (unsigned long)(loopPasses - tasksPasses), temperatureRead());
|
||||
std::vector<TaskSample>().swap(tasksBefore);
|
||||
}
|
||||
|
||||
@@ -421,6 +428,7 @@ static const char* const kHelp =
|
||||
#ifdef RORO_DEBUG
|
||||
"crash abort|wdt crash on purpose (to test crash reports and Safe Mode)\n"
|
||||
"wifi ip ... try <seconds> | wifi ip keep a trial IP setting: back to the previous one unless kept\n"
|
||||
"loop spin on|off make the main loop spin without resting, to compare load and radio noise\n"
|
||||
"lora inject <hex> [rssi] [snr] a packet into the LoRa Scanner as if received (nothing is sent)\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"
|
||||
@@ -448,9 +456,16 @@ static void runCommand(String line) {
|
||||
console.printf("update: %s\n", update->onProbation() ? "on probation" : "confirmed");
|
||||
system_info::printSlots(console, nvs);
|
||||
}
|
||||
#ifdef RORO_DEBUG
|
||||
if (line == "loop spin on" || line == "loop spin off") {
|
||||
loopSpin = line.endsWith("on");
|
||||
console.printf("loop: %s\n", loopSpin ? "spinning, no rest" : "resting between passes");
|
||||
}
|
||||
#endif
|
||||
if (line == "tasks") { // sampled now, printed a second later by tasksStep(): the loop must run in between
|
||||
tasksTotal = system_info::sampleTasks(tasksBefore);
|
||||
tasksDueMs = millis() + 1000;
|
||||
tasksPasses = loopPasses;
|
||||
tasksPending = true;
|
||||
}
|
||||
if (line == "net") { // bytes each service has read and written since boot (S1, Q121)
|
||||
@@ -778,8 +793,30 @@ static void loopSafeMode() {
|
||||
delay(10);
|
||||
}
|
||||
|
||||
// How long the main loop rests after a pass (issue #40). Spinning, it made 50,000 passes a
|
||||
// second and kept core 1 100 % busy for nothing: keys are buffered by the keyboard controller,
|
||||
// the consoles and the radio have their own tasks, and no Service asks for a tick more often than
|
||||
// every 50 ms. Shorter with the screen on, so a key or a redraw never waits long.
|
||||
constexpr uint32_t kLoopRestScreenOnMs = 5;
|
||||
constexpr uint32_t kLoopRestScreenOffMs = 20;
|
||||
static void loopPass();
|
||||
|
||||
void loop() {
|
||||
if (safeMode) return loopSafeMode();
|
||||
loopPasses++;
|
||||
if (safeMode) {
|
||||
loopSafeMode();
|
||||
delay(kLoopRestScreenOnMs);
|
||||
return;
|
||||
}
|
||||
loopPass();
|
||||
#ifdef RORO_DEBUG
|
||||
if (loopSpin) return;
|
||||
#endif
|
||||
if (upload.active()) return; // a serial file transfer: every byte is read promptly
|
||||
delay(power->screen() == ScreenState::Off ? kLoopRestScreenOffMs : kLoopRestScreenOnMs);
|
||||
}
|
||||
|
||||
static void loopPass() {
|
||||
#ifdef RORO_TEST_CRASH
|
||||
// Test builds only (never in a release): crash during Probation to exercise Rollback.
|
||||
if (millis() > 5000) abort();
|
||||
|
||||
Reference in New Issue
Block a user