route zephcore_rtc_save() through the deferred-to-main-thread mechanism

This commit is contained in:
liquidraver
2026-06-08 09:01:18 +02:00
parent 2ad185bab4
commit 6861822127
3 changed files with 83 additions and 6 deletions
+25 -2
View File
@@ -88,7 +88,8 @@ static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
#define MESH_EVENT_HOUSEKEEPING BIT(3) /* Periodic housekeeping (noise floor, etc.) */
#define MESH_EVENT_GPS_ACTION BIT(4) /* GPS state change (must run on main thread!) */
#define MESH_EVENT_TX_DRAIN BIT(5) /* Outbound packet delay expired, run checkSend */
#define MESH_EVENT_ALL (MESH_EVENT_LORA_RX | MESH_EVENT_LORA_TX_DONE | MESH_EVENT_CLI_RX | MESH_EVENT_HOUSEKEEPING | MESH_EVENT_GPS_ACTION | MESH_EVENT_TX_DRAIN)
#define MESH_EVENT_RTC_SAVE BIT(6) /* Hardware-RTC write requested off-main */
#define MESH_EVENT_ALL (MESH_EVENT_LORA_RX | MESH_EVENT_LORA_TX_DONE | MESH_EVENT_CLI_RX | MESH_EVENT_HOUSEKEEPING | MESH_EVENT_GPS_ACTION | MESH_EVENT_TX_DRAIN | MESH_EVENT_RTC_SAVE)
/* Housekeeping interval - infrequent to preserve power savings */
#define HOUSEKEEPING_INTERVAL_MS CONFIG_ZEPHCORE_HOUSEKEEPING_INTERVAL_MS
@@ -96,6 +97,18 @@ static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
/* Event object for mesh loop */
static struct k_event mesh_events;
/* Pending epoch for a deferred zephcore_rtc_save() — gps_fix_callback runs on
* the GNSS modem_chat worker thread, where the RTC's blocking I2C transactions
* would stall NMEA ingest. Stash the latest epoch and let the main thread
* perform the write; concurrent posts coalesce into one save. */
static atomic_t pending_rtc_epoch = ATOMIC_INIT(0);
static void request_rtc_save(uint32_t epoch)
{
atomic_set(&pending_rtc_epoch, (atomic_val_t)epoch);
k_event_post(&mesh_events, MESH_EVENT_RTC_SAVE);
}
/* USB CDC state */
static const struct device *usb_dev;
static uint8_t usb_ring_buf_data[USB_RING_BUF_SIZE];
@@ -272,7 +285,10 @@ static void gps_fix_callback(double lat, double lon, int64_t utc_time)
if (utc_time > 0) {
LOG_INF("GPS fix: RTC sync time=%lld", utc_time);
rtc_clock.setCurrentTime((uint32_t)utc_time);
zephcore_rtc_save((uint32_t)utc_time); /* persist to hardware RTC */
/* Defer the hardware-RTC write to the main thread — blocking I2C
* here would stall NMEA ingest (gps_fix_callback runs in the
* GNSS modem_chat worker context). */
request_rtc_save((uint32_t)utc_time);
}
int lat_deg = (int)lat;
@@ -385,6 +401,13 @@ static void repeater_event_loop(void)
* a 30 s freshness guard — no periodic ADC fire here. */
#endif
}
/* Off-main RTC write request (gps_fix_callback runs in modem_chat
* context — see request_rtc_save()). Perform the blocking I2C
* write here on the main thread instead. */
if (events & MESH_EVENT_RTC_SAVE) {
zephcore_rtc_save((uint32_t)atomic_get(&pending_rtc_epoch));
}
}
}