Add recorder: raw CAN and GNSS sessions with failsafes and a storage bound
Reads SocketCAN and gpsd directly. Sessions start on the first frame or on 'ctl start', end after 15 s of bus idle or on 'ctl stop'; blips under 3 s are discarded. candump -L chunks fdatasync'd every second and zstd'd once closed; oldest sessions deleted to stay under 50 GB / above 20 GB free. Kernel and queue drops, link changes and clock steps are recorded as events. Bench-tested on vcan with the first car capture (byte-identical) and installed on the car Orin as yukart-recorder.service. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
//! The car unit has no RTC battery: the clock boots stale and is stepped later by
|
||||
//! chrony (NTP or GNSS). Recordings therefore carry enough to correct timestamps
|
||||
//! afterwards — sync state at start, monotonic time, and every step observed.
|
||||
|
||||
use serde_json::{json, Value};
|
||||
|
||||
fn clock(id: libc::clockid_t) -> f64 {
|
||||
let mut ts: libc::timespec = unsafe { std::mem::zeroed() };
|
||||
unsafe { libc::clock_gettime(id, &mut ts) };
|
||||
ts.tv_sec as f64 + ts.tv_nsec as f64 * 1e-9
|
||||
}
|
||||
|
||||
pub fn realtime() -> f64 {
|
||||
clock(libc::CLOCK_REALTIME)
|
||||
}
|
||||
|
||||
pub fn monotonic() -> f64 {
|
||||
clock(libc::CLOCK_MONOTONIC)
|
||||
}
|
||||
|
||||
/// realtime − monotonic. Constant while the clock only slews; a jump means a step.
|
||||
pub fn offset() -> f64 {
|
||||
realtime() - monotonic()
|
||||
}
|
||||
|
||||
pub fn boot_id() -> String {
|
||||
std::fs::read_to_string("/proc/sys/kernel/random/boot_id").map(|s| s.trim().to_string()).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Kernel view of synchronisation, read without privilege (adjtimex with modes = 0).
|
||||
pub fn sync_state() -> Value {
|
||||
let mut tx: libc::timex = unsafe { std::mem::zeroed() };
|
||||
let state = unsafe { libc::adjtimex(&mut tx) };
|
||||
let unsync = state == libc::TIME_ERROR || tx.status & libc::STA_UNSYNC != 0;
|
||||
json!({ "synced": !unsync, "maxerror_us": tx.maxerror, "esterror_us": tx.esterror })
|
||||
}
|
||||
|
||||
pub fn hostname() -> String {
|
||||
std::fs::read_to_string("/proc/sys/kernel/hostname").map(|s| s.trim().to_string()).unwrap_or_default()
|
||||
}
|
||||
Reference in New Issue
Block a user