use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash}; /// A region in flash used by the bootloader. #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Partition { /// The offset into the flash where the partition starts. pub from: usize, /// The offset into the flash where the partition ends. pub to: usize, } impl Partition { /// Create a new partition with the provided range pub const fn new(from: usize, to: usize) -> Self { Self { from, to } } /// Return the size of the partition #[allow(clippy::len_without_is_empty)] pub const fn len(&self) -> usize { self.to - self.from } /// Read from the partition on the provided flash pub(crate) async fn read( &self, flash: &mut F, offset: u32, bytes: &mut [u8], ) -> Result<(), F::Error> { let offset = self.from as u32 + offset; flash.read(offset, bytes).await } /// Write to the partition on the provided flash pub(crate) async fn write( &self, flash: &mut F, offset: u32, bytes: &[u8], ) -> Result<(), F::Error> { let offset = self.from as u32 + offset; flash.write(offset, bytes).await?; trace!("Wrote from 0x{:x} len {}", offset, bytes.len()); Ok(()) } /// Erase part of the partition on the provided flash pub(crate) async fn erase(&self, flash: &mut F, from: u32, to: u32) -> Result<(), F::Error> { let from = self.from as u32 + from; let to = self.from as u32 + to; flash.erase(from, to).await?; trace!("Erased from 0x{:x} to 0x{:x}", from, to); Ok(()) } /// Erase the entire partition pub(crate) async fn wipe(&self, flash: &mut F) -> Result<(), F::Error> { let from = self.from as u32; let to = self.to as u32; flash.erase(from, to).await?; trace!("Wiped from 0x{:x} to 0x{:x}", from, to); Ok(()) } /// Read from the partition on the provided flash pub(crate) fn read_blocking( &self, flash: &mut F, offset: u32, bytes: &mut [u8], ) -> Result<(), F::Error> { let offset = self.from as u32 + offset; flash.read(offset, bytes) } /// Write to the partition on the provided flash pub(crate) fn write_blocking(&self, flash: &mut F, offset: u32, bytes: &[u8]) -> Result<(), F::Error> { let offset = self.from as u32 + offset; flash.write(offset, bytes)?; trace!("Wrote from 0x{:x} len {}", offset, bytes.len()); Ok(()) } /// Erase part of the partition on the provided flash pub(crate) fn erase_blocking(&self, flash: &mut F, from: u32, to: u32) -> Result<(), F::Error> { let from = self.from as u32 + from; let to = self.from as u32 + to; flash.erase(from, to)?; trace!("Erased from 0x{:x} to 0x{:x}", from, to); Ok(()) } /// Erase the entire partition pub(crate) fn wipe_blocking(&self, flash: &mut F) -> Result<(), F::Error> { let from = self.from as u32; let to = self.to as u32; flash.erase(from, to)?; trace!("Wiped from 0x{:x} to 0x{:x}", from, to); Ok(()) } }