file up & download and delete

This commit is contained in:
2025-09-18 01:39:32 +02:00
parent cd63e76469
commit 584d6df2d0
6 changed files with 341 additions and 205 deletions

View File

@@ -6,7 +6,7 @@ use anyhow::{anyhow, bail, Context};
use chrono::{DateTime, Utc};
use serde::Serialize;
use crate::hal::LittleFS2StorageAdapter::LittleFs2Filesystem;
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
use alloc::string::ToString;
use alloc::sync::Arc;
use alloc::{format, string::String, vec::Vec};
@@ -34,7 +34,7 @@ use esp_wifi::wifi::{
ScanTypeConfig, WifiController, WifiDevice, WifiEvent, WifiState,
};
use littlefs2::fs::Filesystem;
use littlefs2_core::{FileType, PathBuf};
use littlefs2_core::{DynFile, FileType, OpenSeekFrom, Path, PathBuf, SeekFrom};
use log::{info, warn};
#[link_section = ".rtc.data"]
@@ -113,6 +113,79 @@ macro_rules! mk_static {
}
impl Esp<'_> {
pub(crate) async fn delete_file(&self, filename: String) -> anyhow::Result<()> {
let file = PathBuf::try_from(filename.as_str()).unwrap();
let access = self.fs.lock().await;
access
.remove(&*file)
.map_err(|err| anyhow!("Could not delete file: {:?}", err))?;
Ok(())
}
pub(crate) async fn write_file(
&mut self,
filename: String,
offset: u32,
buf: &[u8],
) -> anyhow::Result<()> {
let file = PathBuf::try_from(filename.as_str()).unwrap();
let access = self.fs.lock().await;
info!("write file {} at offset {}", filename, offset);
match access.open_file_with_options_and_then(
|options| options.read(true).write(true).create(true),
&*file,
|file| {
file.seek(SeekFrom::Start(offset))?;
file.write(buf)?;
Ok(())
},
) {
Ok(_) => Ok(()),
Err(err) => {
bail!(format!("{err:?}"))
}
}
}
pub(crate) async fn get_file(
&mut self,
filename: String,
chunk: u32,
) -> anyhow::Result<([u8; 128], usize)> {
use littlefs2::io::Error as lfs2Error;
let file = PathBuf::try_from(filename.as_str()).unwrap();
let access = self.fs.lock().await;
let mut buf = [0_u8; 128];
let mut read = 0;
let offset = chunk * 128;
info!("read file {} at offset {}", filename, offset);
match access.open_file_with_options_and_then(
|options| options.read(true),
&*file,
|file| {
let length = file.len()? as u32;
info!("file length {}", length);
if length == 0 {
Err(lfs2Error::IO)
} else if length > offset {
file.seek(SeekFrom::Start(offset))?;
info!("seek to {}", offset);
read = file.read(&mut buf)?;
info!("read {} bytes", read);
Ok(())
} else {
//exactly at end, do nothing
Ok(())
}
},
) {
Ok(_) => {}
Err(err) => {
bail!(format!("{err:?}"))
}
}
Ok((buf, read))
}
pub(crate) fn get_ota_slot(&mut self) -> String {
match self.ota.current_slot() {
Ok(slot) => {
@@ -435,11 +508,12 @@ impl Esp<'_> {
match self.fs.lock().await.read_dir_and_then(&path, |dir| {
for entry in dir {
let e = entry?;
result.files.push(FileInfo {
filename: e.path().to_string(),
size: e.metadata().len(),
});
if e.file_type() == FileType::File {
result.files.push(FileInfo {
filename: e.path().to_string(),
size: e.metadata().len(),
});
}
}
Result::Ok(())
}) {
@@ -450,16 +524,7 @@ impl Esp<'_> {
}
Ok(result)
}
pub(crate) async fn delete_file(&self, _filename: &str) -> anyhow::Result<()> {
bail!("todo");
// let filepath = Path::new(Self::BASE_PATH).join(Path::new(filename));
// match fs::remove_file(filepath) {
// OkStd(_) => anyhow::Ok(()),
// Err(err) => {
// bail!(format!("{err:?}"))
// }
// }
}
// pub(crate) async fn get_file_handle(
// &self,
// filename: &str,
@@ -473,13 +538,17 @@ impl Esp<'_> {
// })
// }
pub(crate) fn init_rtc_deepsleep_memory(&self, init_rtc_store: bool, to_config_mode: bool) {
pub(crate) async fn init_rtc_deepsleep_memory(
&self,
init_rtc_store: bool,
to_config_mode: bool,
) {
if init_rtc_store {
unsafe {
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
LOW_VOLTAGE_DETECTED = false;
crate::log::init();
crate::log::init().await;
RESTART_TO_CONF = to_config_mode;
};
} else {
@@ -493,14 +562,16 @@ impl Esp<'_> {
0,
"",
"",
);
)
.await;
log(
LogMessage::LowVoltage,
LOW_VOLTAGE_DETECTED as u32,
0,
"",
"",
);
)
.await;
for i in 0..PLANT_COUNT {
log::info!(
"LAST_WATERING_TIMESTAMP[{}] = UTC {}",

View File

@@ -1,8 +1,8 @@
use embedded_storage::{ReadStorage, Storage};
use esp_bootloader_esp_idf::partitions::FlashRegion;
use esp_storage::FlashStorage;
use littlefs2::consts::U1 as lfs2Array1;
use littlefs2::consts::U512 as lfs2Array512;
use littlefs2::consts::U512 as lfsCache;
use littlefs2::consts::U512 as lfsLookahead;
use littlefs2::driver::Storage as lfs2Storage;
use littlefs2::fs::Filesystem as lfs2Filesystem;
use littlefs2::io::Error as lfs2Error;
@@ -14,20 +14,15 @@ pub struct LittleFs2Filesystem {
}
impl lfs2Storage for LittleFs2Filesystem {
const READ_SIZE: usize = 512;
const READ_SIZE: usize = 256;
const WRITE_SIZE: usize = 512;
const BLOCK_SIZE: usize = 1024; //usually optimal for flash access
const BLOCK_COUNT: usize = 8 * 1024 * 1024 / 1024; //8mb in 32kb blocks
const BLOCK_SIZE: usize = 512; //usually optimal for flash access
const BLOCK_COUNT: usize = 8 * 1024 * 1024 / 512; //8mb in 32kb blocks
const BLOCK_CYCLES: isize = 100;
type CACHE_SIZE = lfs2Array512;
type LOOKAHEAD_SIZE = lfs2Array1;
type CACHE_SIZE = lfsCache;
type LOOKAHEAD_SIZE = lfsLookahead;
fn read(&mut self, off: usize, buf: &mut [u8]) -> lfs2Result<usize> {
info!(
"Littlefs2Filesystem read at offset {} with len {}",
off,
buf.len()
);
let read_size: usize = Self::READ_SIZE;
assert_eq!(off % read_size, 0);
assert_eq!(buf.len() % read_size, 0);

View File

@@ -1,7 +1,7 @@
mod LittleFS2StorageAdapter;
pub(crate) mod battery;
pub mod esp;
mod initial_hal;
mod little_fs2storage_adapter;
mod rtc;
//mod water;
@@ -34,12 +34,10 @@ use esp_bootloader_esp_idf::partitions::{
};
use esp_hal::clock::CpuClock;
use esp_hal::gpio::{Input, InputConfig, Pull};
use esp_println::println;
use measurements::{Current, Voltage};
use crate::hal::LittleFS2StorageAdapter::LittleFs2Filesystem;
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
use embassy_sync::mutex::Mutex;
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
use esp_alloc as _;
use esp_backtrace as _;
use esp_bootloader_esp_idf::ota::Slot;
@@ -182,6 +180,7 @@ impl PlantHal {
let peripherals: Peripherals = esp_hal::init(config);
esp_alloc::heap_allocator!(size: 64 * 1024);
esp_alloc::heap_allocator!(#[link_section = ".dram2_uninit"] size: 64000);
let systimer = SystemTimer::new(peripherals.SYSTIMER);
let boot_button = Input::new(
@@ -364,9 +363,11 @@ impl PlantHal {
to_config_mode as u32,
"",
&format!("{reasons:?}"),
);
)
.await;
esp.init_rtc_deepsleep_memory(init_rtc_store, to_config_mode);
esp.init_rtc_deepsleep_memory(init_rtc_store, to_config_mode)
.await;
let config = esp.load_config().await;
@@ -453,7 +454,8 @@ impl PlantHal {
0,
"",
&err.to_string(),
);
)
.await;
HAL {
board_hal: initial_hal::create_initial_board(
free_pins,