Public Access
Peak stack use was measured through each task's worst case (an ECDSA-checked install over Wi-Fi and from SD, get/put, a core dump fetch, an IRC TLS handshake); stacks are now peak plus about 2 KB: loop 8 -> 6 KB, update 8 -> 5, storage 10 -> 6, irc 8 -> 6. The Debug Build's console ring goes 6 -> 4 KB, serial TX 2 -> 1 KB, the GNSS UART buffer 1 KB -> 512 B. On the device, with IRC on TLS: 46 KB free (was 31), an 18 KB low (was 9.4). The re-run of every worst case left at least 1.6 KB of stack free in each task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
85 lines
3.3 KiB
C++
85 lines
3.3 KiB
C++
#pragma once
|
|
|
|
#include <Print.h>
|
|
|
|
#include <string>
|
|
|
|
#include "event_bus.h"
|
|
#include "nmea_parser.h"
|
|
#include "service.h"
|
|
#include "services/clock_service.h"
|
|
#include "services/storage_service.h"
|
|
#include "settings.h"
|
|
#include "track.h"
|
|
|
|
namespace roro {
|
|
|
|
// The GNSS receiver on the Cap LoRa-1262 (see CONTEXT.md and docs/milestones/M2.md): reads its
|
|
// NMEA from the main loop's tick (about 450 bytes/s, so a 512-byte UART buffer covers a second),
|
|
// holds the current Fix, and sets the clock from it. Settings → GNSS switches it on and off.
|
|
class GnssService : public Service {
|
|
public:
|
|
static constexpr int kRxPin = 15, kTxPin = 13; // measured: M2 step 1
|
|
static constexpr uint32_t kBaud = 115200;
|
|
static constexpr uint32_t kSilentAfterMs = 3000; // no sentence for this long: receiver silent
|
|
static constexpr uint32_t kClockEveryMs = 600000; // refresh the clock from the Fix this often
|
|
// Off (Q58, measured): "$PCAS12,<s>" puts the receiver in standby for that long, and any
|
|
// command wakes it. Standby is renewed while off, in case the duration is clamped.
|
|
static constexpr uint32_t kStandbyRenewMs = 3600000;
|
|
|
|
GnssService(const Settings& settings, ClockService& clock, StorageService& storage, EventBus& bus);
|
|
const char* name() const override { return "gnss"; }
|
|
uint32_t tickIntervalMs() const override { return 50; }
|
|
void start() override;
|
|
void stop() override;
|
|
void tick(uint32_t nowMs) override;
|
|
|
|
bool on() const { return active_; }
|
|
bool receiving(uint32_t nowMs) const { return active_ && lastLineMs_ && nowMs - lastLineMs_ < kSilentAfterMs; }
|
|
const gnss::GnssState& state() const { return parser_.state(); }
|
|
uint32_t onSinceMs() const { return openedMs_; } // when the receiver was last woken
|
|
|
|
// Debug aids (Q68): raw sentences to the console, a status report, and sending a command
|
|
// ("PCAS10,0" becomes "$PCAS10,0*1C\r\n").
|
|
void setEcho(bool echo) { echo_ = echo; }
|
|
void printStatus(Print& out, uint32_t nowMs) const;
|
|
bool send(const std::string& body);
|
|
// Tracks (Q63): GPX on the SD card, a point every 5 s once moved 5 m, recorded in the
|
|
// background whatever App is open. startTrack() returns why it can't, or "".
|
|
std::string startTrack(uint32_t nowMs);
|
|
void stopTrack();
|
|
bool tracking() const { return !trackPath_.empty(); }
|
|
int trackPoints() const { return trackPoints_; }
|
|
uint32_t trackStartMs() const { return trackStartMs_; }
|
|
|
|
void restart(uint32_t nowMs) {
|
|
close();
|
|
open(nowMs);
|
|
}
|
|
|
|
private:
|
|
void open(uint32_t nowMs); // the UART; the receiver's state follows the setting in tick()
|
|
void close();
|
|
void wake(uint32_t nowMs);
|
|
void recordPoint(uint32_t nowMs);
|
|
void closeUnfinishedTracks(); // on the storage task
|
|
void notify(const std::string& text);
|
|
void standby(uint32_t nowMs);
|
|
|
|
const Settings& settings_;
|
|
ClockService& clock_;
|
|
StorageService& storage_;
|
|
EventBus& bus_;
|
|
gnss::NmeaParser parser_;
|
|
bool open_ = false, active_ = false, echo_ = false;
|
|
uint32_t bytes_ = 0, standbyMs_ = 0;
|
|
uint32_t openedMs_ = 0, lastLineMs_ = 0, firstFixMs_ = 0, clockSetMs_ = 0;
|
|
gnss::FixType lastFix_ = gnss::FixType::None;
|
|
std::string trackPath_;
|
|
int trackPoints_ = 0;
|
|
uint32_t trackStartMs_ = 0;
|
|
gnss::TrackRule trackRule_;
|
|
};
|
|
|
|
} // namespace roro
|