#[cfg(feature = "nightly")] mod asynch; mod blocking; use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind}; use crate::Partition; /// Errors returned by FirmwareUpdater #[derive(Debug)] pub enum FirmwareUpdaterError { /// Error from flash. Flash(NorFlashErrorKind), /// Signature errors. Signature(signature::Error), } #[cfg(feature = "defmt")] impl defmt::Format for FirmwareUpdaterError { fn format(&self, fmt: defmt::Formatter) { match self { FirmwareUpdaterError::Flash(_) => defmt::write!(fmt, "FirmwareUpdaterError::Flash(_)"), FirmwareUpdaterError::Signature(_) => defmt::write!(fmt, "FirmwareUpdaterError::Signature(_)"), } } } impl From for FirmwareUpdaterError where E: NorFlashError, { fn from(error: E) -> Self { FirmwareUpdaterError::Flash(error.kind()) } } /// FirmwareUpdater is an application API for interacting with the BootLoader without the ability to /// 'mess up' the internal bootloader state pub struct FirmwareUpdater { state: Partition, dfu: Partition, } #[cfg(target_os = "none")] impl Default for FirmwareUpdater { fn default() -> Self { extern "C" { static __bootloader_state_start: u32; static __bootloader_state_end: u32; static __bootloader_dfu_start: u32; static __bootloader_dfu_end: u32; } let dfu = unsafe { Partition::new( &__bootloader_dfu_start as *const u32 as u32, &__bootloader_dfu_end as *const u32 as u32, ) }; let state = unsafe { Partition::new( &__bootloader_state_start as *const u32 as u32, &__bootloader_state_end as *const u32 as u32, ) }; trace!("DFU: 0x{:x} - 0x{:x}", dfu.from, dfu.to); trace!("STATE: 0x{:x} - 0x{:x}", state.from, state.to); FirmwareUpdater::new(dfu, state) } }