89 lines
3.6 KiB
Rust
89 lines
3.6 KiB
Rust
use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash};
|
|
use esp_bootloader_esp_idf::partitions::FlashRegion;
|
|
use esp_storage::FlashStorage;
|
|
use littlefs2::consts::U4096 as lfsCache;
|
|
use littlefs2::consts::U512 as lfsLookahead;
|
|
use littlefs2::driver::Storage as lfs2Storage;
|
|
use littlefs2::io::Error as lfs2Error;
|
|
use littlefs2::io::Result as lfs2Result;
|
|
use log::error;
|
|
|
|
pub struct LittleFs2Filesystem {
|
|
pub(crate) storage: &'static mut FlashRegion<'static, FlashStorage>,
|
|
}
|
|
|
|
impl lfs2Storage for LittleFs2Filesystem {
|
|
const READ_SIZE: usize = 4096;
|
|
const WRITE_SIZE: usize = 4096;
|
|
const BLOCK_SIZE: usize = 4096; //usually optimal for flash access
|
|
const BLOCK_COUNT: usize = 8 * 1000 * 1000 / 4096; //8Mb in 4k blocks + a little space for stupid calculation errors
|
|
const BLOCK_CYCLES: isize = 100;
|
|
type CACHE_SIZE = lfsCache;
|
|
type LOOKAHEAD_SIZE = lfsLookahead;
|
|
|
|
fn read(&mut self, off: usize, buf: &mut [u8]) -> lfs2Result<usize> {
|
|
let read_size: usize = Self::READ_SIZE;
|
|
if off % read_size != 0 {
|
|
error!("Littlefs2Filesystem read error: offset not aligned to read size offset: {} read_size: {}", off, read_size);
|
|
return Err(lfs2Error::IO);
|
|
}
|
|
if buf.len() % read_size != 0 {
|
|
error!("Littlefs2Filesystem read error: length not aligned to read size length: {} read_size: {}", buf.len(), read_size);
|
|
return Err(lfs2Error::IO);
|
|
}
|
|
match self.storage.read(off as u32, buf) {
|
|
Ok(..) => Ok(buf.len()),
|
|
Err(err) => {
|
|
error!("Littlefs2Filesystem read error: {:?}", err);
|
|
Err(lfs2Error::IO)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn write(&mut self, off: usize, data: &[u8]) -> lfs2Result<usize> {
|
|
let write_size: usize = Self::WRITE_SIZE;
|
|
if off % write_size != 0 {
|
|
error!("Littlefs2Filesystem write error: offset not aligned to write size offset: {} write_size: {}", off, write_size);
|
|
return Err(lfs2Error::IO);
|
|
}
|
|
if data.len() % write_size != 0 {
|
|
error!("Littlefs2Filesystem write error: length not aligned to write size length: {} write_size: {}", data.len(), write_size);
|
|
return Err(lfs2Error::IO);
|
|
}
|
|
match self.storage.write(off as u32, data) {
|
|
Ok(..) => Ok(data.len()),
|
|
Err(err) => {
|
|
error!("Littlefs2Filesystem write error: {:?}", err);
|
|
Err(lfs2Error::IO)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn erase(&mut self, off: usize, len: usize) -> lfs2Result<usize> {
|
|
let block_size: usize = Self::BLOCK_SIZE;
|
|
if off % block_size != 0 {
|
|
error!("Littlefs2Filesystem erase error: offset not aligned to block size offset: {} block_size: {}", off, block_size);
|
|
return lfs2Result::Err(lfs2Error::IO);
|
|
}
|
|
if len % block_size != 0 {
|
|
error!("Littlefs2Filesystem erase error: length not aligned to block size length: {} block_size: {}", len, block_size);
|
|
return lfs2Result::Err(lfs2Error::IO);
|
|
}
|
|
|
|
match check_erase(self.storage, off as u32, (off+len) as u32) {
|
|
Ok(_) => {}
|
|
Err(err) => {
|
|
error!("Littlefs2Filesystem check erase error: {:?}", err);
|
|
return lfs2Result::Err(lfs2Error::IO);
|
|
}
|
|
}
|
|
match self.storage.erase(off as u32, (off + len) as u32) {
|
|
Ok(..) => lfs2Result::Ok(len),
|
|
Err(err) => {
|
|
error!("Littlefs2Filesystem erase error: {:?}", err);
|
|
lfs2Result::Err(lfs2Error::IO)
|
|
}
|
|
}
|
|
}
|
|
}
|