Add TimeDiscipline
parent
ad70b3a010
commit
bb500d7966
1 changed files with 120 additions and 0 deletions
120
TimeDiscipline.md
Normal file
120
TimeDiscipline.md
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
2/20/26 -- files on the SD cards are all time-stamped 1980! Despite having an exercise to discipline time, it looks like I missed making sure the file system also observed time.
|
||||||
|

|
||||||
|
### My prompt:
|
||||||
|
If the battery is removed, then the RTC faults. The T-Beams need to be programmed so that they immediately ascertain a correct time. We could use January 1, 2026, as a milestone and if the system's clock does not have something later, then it must alert the user that the RTC is off [probably because of power disconnect and battery removal] and to place the unit so it can ascertain time from GPS. The unit could have a holding pattern of 5 minutes to allow for moving the unit within satellite view and ascertaining GPS time, or then default to its zero-based time. We could have a user prompt action to bypass this waiting period, e.g. pressing the BOOT or POWER button. I'm treating these units as single board computers, which they are, and establishing time is critical. This has been very helpful and will help solidify what I am assembling for a code base for the T-Beam.
|
||||||
|
|
||||||
|
### ChatGPT response:
|
||||||
|
You’re thinking about it exactly the right way: treat “time discipline” as a first-class system service, not a convenience. On these boards, a dead/removed RTC battery turns “filesystem metadata” and any time-series logging into fiction unless you actively manage it.
|
||||||
|
|
||||||
|
Here’s a clean, SBC-style design that fits what you described and is straightforward to implement.
|
||||||
|
|
||||||
|
## Policy
|
||||||
|
|
||||||
|
### Time validity rule
|
||||||
|
|
||||||
|
* Define a “milestone” epoch: **2026-01-01 00:00:00 UTC**.
|
||||||
|
* If `now < milestone`, treat system time as **INVALID**.
|
||||||
|
|
||||||
|
This is better than checking for 1980 because it catches *any* bogus RTC reset scenario.
|
||||||
|
|
||||||
|
### Boot behavior
|
||||||
|
|
||||||
|
1. **Early boot:** initialize RTC/GPS subsystems but do **not** create “real” log files yet.
|
||||||
|
2. If time is invalid:
|
||||||
|
|
||||||
|
* **Alert** clearly (screen/LED/buzzer/serial).
|
||||||
|
* Enter a **time-acquire holding pattern** for up to **300 seconds**.
|
||||||
|
* Allow a **user bypass** (BOOT or POWER) to skip the wait.
|
||||||
|
3. If time becomes valid during the window:
|
||||||
|
|
||||||
|
* Set system clock from GPS time.
|
||||||
|
* Mark “time valid” and proceed to normal operation.
|
||||||
|
4. If still invalid after timeout or user bypass:
|
||||||
|
|
||||||
|
* Continue in **degraded mode**:
|
||||||
|
|
||||||
|
* Use a **zero-based monotonic clock** for internal intervals.
|
||||||
|
* Write logs with a **DEGRADED** marker and the boot-relative timestamp.
|
||||||
|
* Keep trying GPS in the background, and once valid, “roll over” into normal logs.
|
||||||
|
|
||||||
|
## Filesystem and logging implications
|
||||||
|
|
||||||
|
### Don’t create 1980-stamped files
|
||||||
|
|
||||||
|
Two practical rules:
|
||||||
|
|
||||||
|
* **Don’t open the SD log file until time is valid**, *or*
|
||||||
|
* Write to a temporary file (`BOOTSTRAP.log`) and rename/rollover once time is valid.
|
||||||
|
|
||||||
|
Because FAT timestamps are set at create/write time, preventing early “bad time” writes prevents 1980 mtimes entirely.
|
||||||
|
|
||||||
|
### Encode time in filenames anyway
|
||||||
|
|
||||||
|
Keep your filename protocol. It’s your forensic ground truth even when mtimes are wrong.
|
||||||
|
|
||||||
|
## User experience details
|
||||||
|
|
||||||
|
### Alerts that don’t annoy you later
|
||||||
|
|
||||||
|
* On invalid time: show something like:
|
||||||
|
|
||||||
|
* `RTC INVALID (now=1980...). Place under sky for GPS. Waiting 5:00. Press BOOT to skip.`
|
||||||
|
* If bypass pressed:
|
||||||
|
|
||||||
|
* `Bypass requested; running without wall-clock. Logs use uptime until GPS sync.`
|
||||||
|
|
||||||
|
### “Holding pattern” that’s actually useful
|
||||||
|
|
||||||
|
During the 5-minute window:
|
||||||
|
|
||||||
|
* Keep the radio stack idle or reduced activity.
|
||||||
|
* Try GPS sync aggressively (e.g., poll 1 Hz).
|
||||||
|
* Show progress: satellites seen, fix status, last GPS time received.
|
||||||
|
|
||||||
|
## Implementation sketch
|
||||||
|
|
||||||
|
### State machine (simple and robust)
|
||||||
|
|
||||||
|
* `TIME_INVALID`
|
||||||
|
* `TIME_WAIT_GPS`
|
||||||
|
* `TIME_VALID`
|
||||||
|
* `TIME_DEGRADED` (invalid but proceeding)
|
||||||
|
Transitions:
|
||||||
|
* invalid at boot → wait
|
||||||
|
* wait + GPS sync → valid
|
||||||
|
* wait timeout or user bypass → degraded
|
||||||
|
* degraded + GPS sync → valid
|
||||||
|
|
||||||
|
### Minimal core functions
|
||||||
|
|
||||||
|
* `bool time_is_valid()`
|
||||||
|
* `bool gps_time_available()`
|
||||||
|
* `void set_system_time_from_gps()`
|
||||||
|
* `bool user_bypass_pressed()`
|
||||||
|
* `void logging_rollover_to_valid_time()`
|
||||||
|
|
||||||
|
## FAT timestamping
|
||||||
|
|
||||||
|
Once system time is valid, make sure the SD stack stamps files from that clock:
|
||||||
|
|
||||||
|
* If you’re using **ESP-IDF/FATFS**: ensure `get_fattime()` is returning the current time (derived from the system clock you set).
|
||||||
|
* If you’re using **SdFat**: ensure the date/time callback is set and returns valid time once GPS sync occurs.
|
||||||
|
|
||||||
|
That’s the mechanical link between “disciplined system time” and “no more 1980.”
|
||||||
|
|
||||||
|
## What I’d put in your codebase docs
|
||||||
|
|
||||||
|
A short “Time Discipline” section like a Linux service doc:
|
||||||
|
|
||||||
|
* **Sources**: RTC (weak), GPS (authoritative)
|
||||||
|
* **Validity threshold**: milestone epoch
|
||||||
|
* **Startup behavior**: wait window + bypass
|
||||||
|
* **Degraded mode**: uptime-based timestamps + explicit markers
|
||||||
|
* **Logging policy**: no SD log creation before time valid; rollover once synced
|
||||||
|
|
||||||
|
If you tell me which stack you’re using for SD + time (`SD`/`SD_MMC` Arduino, SdFat, or ESP-IDF `esp_vfs_fat_sdmmc`), I’ll give you a drop-in implementation pattern for:
|
||||||
|
|
||||||
|
* milestone validity check
|
||||||
|
* 5-minute wait with BOOT bypass
|
||||||
|
* the exact FAT timestamp hook for that stack
|
||||||
|
* safe log rollover so you never mint another “1980” file again
|
||||||
Loading…
Add table
Add a link
Reference in a new issue