stuff
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::bail;
|
||||
use crate::{bail};
|
||||
use crate::config::{NetworkConfig, PlantControllerConfig};
|
||||
use crate::hal::{PLANT_COUNT, TIME_ACCESS};
|
||||
use crate::hal::{get_next_slot, PLANT_COUNT, TIME_ACCESS};
|
||||
use crate::log::{LogMessage, LOG_ACCESS};
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::Serialize;
|
||||
@@ -20,7 +20,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::mutex::{Mutex, MutexGuard};
|
||||
use embassy_sync::once_lock::OnceLock;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
|
||||
use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash};
|
||||
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState};
|
||||
use esp_bootloader_esp_idf::ota::OtaImageState::Valid;
|
||||
use esp_bootloader_esp_idf::partitions::FlashRegion;
|
||||
@@ -30,7 +30,6 @@ use esp_hal::rtc_cntl::{
|
||||
sleep::{TimerWakeupSource, WakeupLevel},
|
||||
Rtc,
|
||||
};
|
||||
use esp_hal::sha::Digest;
|
||||
use esp_hal::system::software_reset;
|
||||
use esp_println::println;
|
||||
use esp_storage::FlashStorage;
|
||||
@@ -214,10 +213,10 @@ impl Esp<'_> {
|
||||
Ok((buf, read))
|
||||
}
|
||||
|
||||
pub(crate) fn get_ota_slot(&mut self) -> String {
|
||||
match self.ota.current_slot() {
|
||||
pub(crate) fn get_current_ota_slot(&mut self) -> String {
|
||||
match get_next_slot(&mut self.ota) {
|
||||
Ok(slot) => {
|
||||
format!("{:?}", slot)
|
||||
format!("{:?}", slot.next())
|
||||
}
|
||||
Err(err) => {
|
||||
format!("{:?}", err)
|
||||
@@ -241,31 +240,77 @@ impl Esp<'_> {
|
||||
offset: u32,
|
||||
buf: &[u8],
|
||||
) -> Result<(), FatError> {
|
||||
if self.ota.current_ota_state() == Ok(OtaImageState::Invalid) {
|
||||
bail!("Invalid OTA state, refusing ota write")
|
||||
}
|
||||
if self.ota.current_ota_state() == Ok(OtaImageState::Undefined) {
|
||||
bail!("Invalid OTA state, refusing ota write")
|
||||
}
|
||||
|
||||
let mut read_back = [0_u8; 1024];
|
||||
let useful = &mut read_back[..buf.len()];
|
||||
//change to nor flash, align writes!
|
||||
self.ota_next.write(offset, buf)?;
|
||||
self.ota_next.read(offset, useful)?;
|
||||
if buf != useful {
|
||||
info!("Expected {:?} but got {:?}", buf, useful);
|
||||
bail!("Flash error, read back does not match write buffer at offset {:x}", offset)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn finalize_ota(
|
||||
pub(crate) async fn ota_erase(&mut self, block_start: u32) -> FatResult<()> {
|
||||
// Ensure 4K block size and alignment
|
||||
if self.ota_next.capacity() % 4096 != 0 {
|
||||
bail!("Partition size is not a multiple of 4096")
|
||||
}
|
||||
if block_start % 4096 != 0 {
|
||||
bail!("ota_erase called with unaligned block_start: {:x}", block_start)
|
||||
}
|
||||
let capacity = self.ota_next.capacity() as u32;
|
||||
if block_start >= capacity {
|
||||
bail!("ota_erase block_start out of range: {:x}", block_start)
|
||||
}
|
||||
let end = core::cmp::min(block_start + 4096, capacity);
|
||||
// Check current erase state (will error if not erased); we ignore the result and erase anyway
|
||||
let _ = check_erase(self.ota_next, block_start, end);
|
||||
info!("erasing block {:x}-{:x}", block_start, end);
|
||||
self.ota_next.erase(block_start, end)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn finalize_ota(
|
||||
&mut self,
|
||||
) -> Result<(), FatError> {
|
||||
if self.ota.current_ota_state() == Ok(OtaImageState::Invalid) {
|
||||
bail!("Invalid OTA state, refusing ota write")
|
||||
}
|
||||
if self.ota.current_ota_state() == Ok(OtaImageState::Undefined) {
|
||||
bail!("Invalid OTA state, refusing ota write")
|
||||
}
|
||||
|
||||
|
||||
let current_state = self.ota.current_ota_state()?;
|
||||
let current_slot = self.ota.current_slot()?;
|
||||
info!("current state {:?}", current_state);
|
||||
let next_slot = get_next_slot(&mut self.ota)?;
|
||||
info!("current slot {:?}", next_slot.next());
|
||||
if current_state == OtaImageState::PendingVerify {
|
||||
info!("verifying ota image from pending");
|
||||
self.ota.set_current_ota_state(Valid)?;
|
||||
}
|
||||
self.ota.set_current_slot(current_slot.next())?;
|
||||
|
||||
self.ota.set_current_slot(next_slot)?;
|
||||
info!("switched slot");
|
||||
self.ota.set_current_ota_state(OtaImageState::New)?;
|
||||
info!("switched state for new partition");
|
||||
let state_new = self.ota.current_ota_state()?;
|
||||
info!("state on new partition now {:?}", state_new);
|
||||
//determine nextslot crc
|
||||
|
||||
self.set_restart_to_conf(true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// let current = ota.current_slot()?;
|
||||
// println!(
|
||||
// "current image state {:?} (only relevant if the bootloader was built with auto-rollback support)",
|
||||
// ota.current_ota_state()
|
||||
// );
|
||||
// println!("current {:?} - next {:?}", current, current.next());
|
||||
// let ota_state = ota.current_ota_state()?;
|
||||
|
||||
pub(crate) fn mode_override_pressed(&mut self) -> bool {
|
||||
self.boot_button.is_low()
|
||||
}
|
||||
@@ -323,11 +368,6 @@ impl Esp<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn flash_ota(&mut self) -> FatResult<()> {
|
||||
let capacity = self.ota_next.capacity();
|
||||
|
||||
bail!("not implemented")
|
||||
}
|
||||
|
||||
pub(crate) async fn wifi_scan(&mut self) -> FatResult<Vec<AccessPointInfo>> {
|
||||
info!("start wifi scan");
|
||||
@@ -616,7 +656,11 @@ impl Esp<'_> {
|
||||
}
|
||||
|
||||
pub(crate) async fn load_config(&mut self) -> FatResult<PlantControllerConfig> {
|
||||
let cfg = PathBuf::try_from(CONFIG_FILE).unwrap();
|
||||
let cfg = PathBuf::try_from(CONFIG_FILE)?;
|
||||
let config_exist = self.fs.lock().await.exists(&cfg);
|
||||
if !config_exist {
|
||||
bail!("No config file stored")
|
||||
}
|
||||
let data = self.fs.lock().await.read::<4096>(&cfg)?;
|
||||
let config: PlantControllerConfig = serde_json::from_slice(&data)?;
|
||||
return Ok(config);
|
||||
|
Reference in New Issue
Block a user