store backup now in binary, and let backend serialize/deserialize

This commit is contained in:
2026-04-05 13:30:11 +02:00
parent 1fa765a5d8
commit 4d4fcbe33b
9 changed files with 121 additions and 204 deletions

View File

@@ -1,8 +1,7 @@
use crate::fat_error::FatResult;
use crate::hal::Box;
use crate::fat_error::FatResult;
use async_trait::async_trait;
use bincode::config::Configuration;
use bincode::{config, Decode, Encode};
use bincode::{Decode, Encode};
use chrono::{DateTime, Utc};
use ds323x::ic::DS3231;
use ds323x::interface::I2cInterface;
@@ -19,24 +18,21 @@ use esp_hal::Blocking;
use serde::{Deserialize, Serialize};
pub const X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
const CONFIG: Configuration = config::standard();
pub const EEPROM_PAGE: usize = 32;
//
#[async_trait(?Send)]
pub trait RTCModuleInteraction {
async fn get_backup_info(&mut self) -> FatResult<BackupHeader>;
async fn get_backup_config(&mut self, chunk: usize) -> FatResult<([u8; 32], usize, u16)>;
async fn backup_config(&mut self, offset: usize, bytes: &[u8]) -> FatResult<()>;
async fn backup_config_finalize(&mut self, crc: u16, length: usize) -> FatResult<()>;
async fn get_rtc_time(&mut self) -> FatResult<DateTime<Utc>>;
async fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> FatResult<()>;
fn write(&mut self, offset: u32, data: &[u8]) -> FatResult<()>;
fn read(&mut self, offset:u32, data: &mut [u8]) -> FatResult<()>;
}
//
const BACKUP_HEADER_MAX_SIZE: usize = 64;
#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Encode, Decode)]
pub struct BackupHeader {
pub timestamp: i64,
crc16: u16,
pub(crate) crc16: u16,
pub size: u16,
}
//
@@ -46,7 +42,7 @@ pub struct DS3231Module {
DS3231,
>,
pub(crate) storage: eeprom24x::Storage<
pub storage: eeprom24x::Storage<
I2cDevice<'static, CriticalSectionRawMutex, I2c<'static, Blocking>>,
B32,
TwoBytes,
@@ -57,67 +53,6 @@ pub struct DS3231Module {
#[async_trait(?Send)]
impl RTCModuleInteraction for DS3231Module {
async fn get_backup_info(&mut self) -> FatResult<BackupHeader> {
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
self.storage.read(0, &mut header_page_buffer)?;
let (header, len): (BackupHeader, usize) =
bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
log::info!("Raw header is {header_page_buffer:?} with size {len}");
Ok(header)
}
async fn get_backup_config(&mut self, chunk: usize) -> FatResult<([u8; 32], usize, u16)> {
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
self.storage.read(0, &mut header_page_buffer)?;
let (header, _header_size): (BackupHeader, usize) =
bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
let mut buf = [0_u8; 32];
let offset = chunk * buf.len() + BACKUP_HEADER_MAX_SIZE;
let end: usize = header.size as usize + BACKUP_HEADER_MAX_SIZE;
let current_end = offset + buf.len();
let chunk_size = if current_end > end {
end - offset
} else {
buf.len()
};
if chunk_size == 0 {
Ok((buf, 0, header.crc16))
} else {
self.storage.read(offset as u32, &mut buf)?;
//&buf[..chunk_size];
Ok((buf, chunk_size, header.crc16))
}
}
async fn backup_config(&mut self, offset: usize, bytes: &[u8]) -> FatResult<()> {
//skip header and write after
self.storage
.write((BACKUP_HEADER_MAX_SIZE + offset) as u32, bytes)?;
Ok(())
}
async fn backup_config_finalize(&mut self, crc: u16, length: usize) -> FatResult<()> {
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
let time = self.get_rtc_time().await?.timestamp_millis();
let header = BackupHeader {
crc16: crc,
timestamp: time,
size: length as u16,
};
let config = config::standard();
let encoded = bincode::encode_into_slice(&header, &mut header_page_buffer, config)?;
log::info!("Raw header is {header_page_buffer:?} with size {encoded}");
self.storage.write(0, &header_page_buffer)?;
Ok(())
}
async fn get_rtc_time(&mut self) -> FatResult<DateTime<Utc>> {
Ok(self.rtc.datetime()?.and_utc())
}
@@ -126,4 +61,14 @@ impl RTCModuleInteraction for DS3231Module {
let naive_time = time.naive_utc();
Ok(self.rtc.set_datetime(&naive_time)?)
}
fn write(&mut self, offset: u32, data: &[u8]) -> FatResult<()> {
self.storage.write(offset, data)?;
Ok(())
}
fn read(&mut self, offset:u32, data: &mut [u8]) -> FatResult<()> {
self.storage.read(offset, data)?;
Ok(())
}
}