seamless crashing
This commit is contained in:
4
TODO.md
4
TODO.md
@@ -9,5 +9,7 @@
|
||||
- needs to have a CLI table output
|
||||
- needs to have a GUI output (matplotlib)
|
||||
- [ ] Refactor; make sure everything adheres to naming conventions
|
||||
- [ ] Bluetooth pairing
|
||||
- [ ] Renaming wifi (should reboot the wifi/web comms to take effect)
|
||||
- [ ] Make sure external RTC crystal is actually in use
|
||||
- [ ] Warn if time is de-synced from client by more than 5 minutes
|
||||
- [ ] Bluetooth pairing
|
||||
@@ -42,7 +42,8 @@ typedef enum {
|
||||
STATE_CALIBRATE_DRIVE_DELAY,
|
||||
STATE_CALIBRATE_DRIVE_MOVE
|
||||
} fsm_state_t;
|
||||
#define LOG_TYPE_BAT 100
|
||||
#define LOG_TYPE_BAT 100
|
||||
#define LOG_TYPE_CRASH 101
|
||||
|
||||
typedef enum {
|
||||
RELAY_SENSORS = 0,
|
||||
|
||||
18
main/main.c
18
main/main.c
@@ -1,4 +1,5 @@
|
||||
#include "esp_task_wdt.h"
|
||||
#include "esp_system.h"
|
||||
#include "i2c.h"
|
||||
#include "log_test.h"
|
||||
#include "storage.h"
|
||||
@@ -109,6 +110,7 @@ void app_main(void) {esp_task_wdt_add(NULL);
|
||||
//run_all_log_tests();
|
||||
|
||||
if (rtc_xtal_init() != ESP_OK) ESP_LOGE(TAG, "RTC FAILED");
|
||||
rtc_restore_time(); // Restore time from RTC backup if we crashed
|
||||
|
||||
// Say hello; turn on the lights
|
||||
esp_sleep_wakeup_cause_t cause = rtc_wakeup_cause();
|
||||
@@ -171,6 +173,21 @@ void app_main(void) {esp_task_wdt_add(NULL);
|
||||
if (adc_init() != ESP_OK) ESP_LOGE(TAG, "ADC FAILED");
|
||||
if (storage_init() != ESP_OK) ESP_LOGE(TAG, "STORAGE FAILED");
|
||||
if (log_init() != ESP_OK) ESP_LOGE(TAG, "LOG FAILED");
|
||||
|
||||
// Write a crash log entry if we rebooted unexpectedly
|
||||
esp_reset_reason_t reset_reason = esp_reset_reason();
|
||||
if (reset_reason == ESP_RST_PANIC ||
|
||||
reset_reason == ESP_RST_INT_WDT ||
|
||||
reset_reason == ESP_RST_TASK_WDT ||
|
||||
reset_reason == ESP_RST_WDT) {
|
||||
ESP_LOGW(TAG, "Crash detected! Reset reason: %d", reset_reason);
|
||||
uint8_t crash_entry[9] = {};
|
||||
uint64_t ts = rtc_get_ms();
|
||||
memcpy(&crash_entry[0], &ts, 8);
|
||||
crash_entry[8] = (uint8_t)reset_reason;
|
||||
log_write(crash_entry, sizeof(crash_entry), LOG_TYPE_CRASH);
|
||||
}
|
||||
|
||||
if (solar_run_fsm() != ESP_OK) ESP_LOGE(TAG, "SOLAR FAILED");
|
||||
// TODO: Do a 12V check and enter deep sleep if there's a problem
|
||||
|
||||
@@ -317,6 +334,7 @@ void app_main(void) {esp_task_wdt_add(NULL);
|
||||
}
|
||||
|
||||
solar_run_fsm();
|
||||
rtc_save_time(); // Keep RTC backup fresh so crashes don't lose time
|
||||
|
||||
rtc_check_shutdown_timer();
|
||||
esp_task_wdt_reset();
|
||||
|
||||
18
main/rtc.c
18
main/rtc.c
@@ -34,9 +34,10 @@
|
||||
|
||||
uint64_t last_activity_tick = 0;
|
||||
|
||||
// RTC_DATA_ATTR keeps this var in RTC memory; persists across sleeps (but not across boots)
|
||||
// RTC_DATA_ATTR keeps these in RTC memory; persists across deep sleep AND software resets (panics, WDT)
|
||||
RTC_DATA_ATTR int64_t next_alarm_time_s = -1;
|
||||
RTC_DATA_ATTR bool rtc_set = false;
|
||||
RTC_DATA_ATTR int64_t rtc_backup_s = 0; // Crash-safe time snapshot
|
||||
bool rtc_is_set() {
|
||||
return rtc_set;
|
||||
}
|
||||
@@ -94,10 +95,25 @@ void rtc_set_s(int64_t tv_sec)
|
||||
{
|
||||
rtc_set = true;
|
||||
settimeofday(&(struct timeval){.tv_sec = tv_sec, .tv_usec=0}, NULL);
|
||||
rtc_backup_s = tv_sec;
|
||||
solar_reset_fsm();
|
||||
rtc_schedule_next_alarm();
|
||||
}
|
||||
|
||||
void rtc_save_time(void)
|
||||
{
|
||||
if (rtc_set)
|
||||
rtc_backup_s = rtc_get_s();
|
||||
}
|
||||
|
||||
void rtc_restore_time(void)
|
||||
{
|
||||
if (rtc_set && rtc_backup_s > 0) {
|
||||
settimeofday(&(struct timeval){.tv_sec = rtc_backup_s, .tv_usec = 0}, NULL);
|
||||
ESP_LOGI("RTC", "Time restored from crash backup: %lld", (long long)rtc_backup_s);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t rtc_get_ms(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
@@ -43,6 +43,9 @@ int64_t rtc_get_s (void);
|
||||
int64_t rtc_get_ms(void);
|
||||
void rtc_set_s(int64_t);
|
||||
|
||||
void rtc_save_time(void); // Snapshot current time to RTC memory (call periodically)
|
||||
void rtc_restore_time(void); // Restore time from RTC backup after a crash reboot
|
||||
|
||||
void rtc_schedule_next_alarm(void);
|
||||
int64_t rtc_get_next_alarm_s();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user