Introduce watchdog and serialization improvements
- Added watchdog timer for improved system stability and responsiveness. - Switched save data serialization to Bincode for better efficiency. - Enhanced compatibility by supporting fallback to older JSON format. - Improved logging during flash operations for easier debugging. - Simplified SavegameManager by managing storage directly.
This commit is contained in:
@@ -3,8 +3,8 @@ use lib_bms_protocol::BmsReadable;
|
||||
pub(crate) mod battery;
|
||||
// mod can_api; // replaced by external canapi crate
|
||||
pub mod esp;
|
||||
pub(crate) mod savegame_manager;
|
||||
pub(crate) mod rtc;
|
||||
pub(crate) mod savegame_manager;
|
||||
mod shared_flash;
|
||||
mod v4_hal;
|
||||
mod water;
|
||||
@@ -85,7 +85,7 @@ use esp_alloc as _;
|
||||
use esp_backtrace as _;
|
||||
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState};
|
||||
use esp_hal::delay::Delay;
|
||||
use esp_hal::i2c::master::{BusTimeout, Config, I2c};
|
||||
use esp_hal::i2c::master::{BusTimeout, Config, FsmTimeout, I2c, SoftwareTimeout};
|
||||
use esp_hal::interrupt::software::SoftwareInterruptControl;
|
||||
use esp_hal::pcnt::unit::Unit;
|
||||
use esp_hal::pcnt::Pcnt;
|
||||
@@ -93,7 +93,7 @@ use esp_hal::rng::Rng;
|
||||
use esp_hal::rtc_cntl::{Rtc, SocResetReason};
|
||||
use esp_hal::system::reset_reason;
|
||||
use esp_hal::time::Rate;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use esp_hal::timer::timg::{MwdtStage, TimerGroup, Wdt};
|
||||
use esp_hal::uart::Uart;
|
||||
use esp_hal::Blocking;
|
||||
use esp_radio::{init, Controller};
|
||||
@@ -108,6 +108,13 @@ pub const PLANT_COUNT: usize = 8;
|
||||
|
||||
pub static PROGRESS_ACTIVE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
pub static WATCHDOG: OnceLock<
|
||||
embassy_sync::blocking_mutex::Mutex<
|
||||
CriticalSectionRawMutex,
|
||||
RefCell<Wdt<esp_hal::peripherals::TIMG0>>,
|
||||
>,
|
||||
> = OnceLock::new();
|
||||
|
||||
const TANK_MULTI_SAMPLE: usize = 11;
|
||||
pub static I2C_DRIVER: OnceLock<
|
||||
embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<I2c<Blocking>>>,
|
||||
@@ -174,6 +181,9 @@ pub trait BoardInteraction<'a> {
|
||||
// Indicate progress is active to suppress default wait_infinity blinking
|
||||
PROGRESS_ACTIVE.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
// Feed watchdog during long-running webserver operations
|
||||
PlantHal::feed_watchdog();
|
||||
|
||||
let current = counter % PLANT_COUNT as u32;
|
||||
for led in 0..PLANT_COUNT {
|
||||
if let Err(err) = self.fault(led, current == led as u32).await {
|
||||
@@ -251,6 +261,16 @@ impl PlantHal {
|
||||
let sw_int = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
|
||||
esp_rtos::start(timg0.timer0, sw_int.software_interrupt0);
|
||||
|
||||
// Initialize and enable the watchdog with 30 second timeout
|
||||
let mut wdt = timg0.wdt;
|
||||
wdt.set_timeout(MwdtStage::Stage0, esp_hal::time::Duration::from_secs(30));
|
||||
wdt.enable();
|
||||
WATCHDOG
|
||||
.init(embassy_sync::blocking_mutex::Mutex::new(RefCell::new(wdt)))
|
||||
.map_err(|_| FatError::String {
|
||||
error: "Watchdog already initialized".to_string(),
|
||||
})?;
|
||||
|
||||
let boot_button = Input::new(
|
||||
peripherals.GPIO9,
|
||||
InputConfig::default().with_pull(Pull::None),
|
||||
@@ -380,7 +400,11 @@ impl PlantHal {
|
||||
);
|
||||
|
||||
let savegame = SavegameManager::new(data);
|
||||
info!("Savegame storage initialized ({} slots × {} KB)", savegame_manager::SAVEGAME_SLOT_COUNT, savegame_manager::SAVEGAME_SLOT_SIZE / 1024);
|
||||
info!(
|
||||
"Savegame storage initialized ({} slots × {} KB)",
|
||||
savegame_manager::SAVEGAME_SLOT_COUNT,
|
||||
savegame_manager::SAVEGAME_SLOT_SIZE / 1024
|
||||
);
|
||||
|
||||
let uart0 =
|
||||
Uart::new(peripherals.UART0, UartConfig::default()).map_err(|_| FatError::String {
|
||||
@@ -458,11 +482,16 @@ impl PlantHal {
|
||||
let sda = peripherals.GPIO20;
|
||||
let scl = peripherals.GPIO19;
|
||||
|
||||
// Configure I2C with 1-second timeout
|
||||
// At 100 Hz I2C clock, one bus cycle = 10ms
|
||||
// For 1 second timeout: 100 bus cycles
|
||||
let i2c = I2c::new(
|
||||
peripherals.I2C0,
|
||||
Config::default()
|
||||
.with_frequency(Rate::from_hz(100))
|
||||
.with_timeout(BusTimeout::Maximum),
|
||||
//.with_frequency(Rate::from_hz(100))
|
||||
//1s at 100khz
|
||||
.with_timeout(BusTimeout::BusCycles(100_000))
|
||||
.with_scl_main_st_timeout(FsmTimeout::new(21)?),
|
||||
)?
|
||||
.with_scl(scl)
|
||||
.with_sda(sda);
|
||||
@@ -563,6 +592,15 @@ impl PlantHal {
|
||||
|
||||
Ok(Mutex::new(hal))
|
||||
}
|
||||
|
||||
/// Feed the watchdog timer to prevent system reset
|
||||
pub fn feed_watchdog() {
|
||||
if let Some(wdt_mutex) = WATCHDOG.try_get() {
|
||||
wdt_mutex.lock(|cell| {
|
||||
cell.borrow_mut().feed();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ota_state(
|
||||
|
||||
Reference in New Issue
Block a user