From c267cb9ab764176bc8514535f4db8ac2331e30ce Mon Sep 17 00:00:00 2001 From: Badr Bouslikhin Date: Tue, 6 Feb 2024 16:25:45 +0100 Subject: feat: enhance bootloader for multiple flash support --- embassy-boot/src/boot_loader.rs | 20 ++++++++++++-------- embassy-boot/src/firmware_updater/asynch.rs | 13 ++++++++----- embassy-boot/src/firmware_updater/blocking.rs | 14 +++++++++----- 3 files changed, 29 insertions(+), 18 deletions(-) (limited to 'embassy-boot/src') diff --git a/embassy-boot/src/boot_loader.rs b/embassy-boot/src/boot_loader.rs index e568001bc..54ae8a34b 100644 --- a/embassy-boot/src/boot_loader.rs +++ b/embassy-boot/src/boot_loader.rs @@ -49,16 +49,20 @@ pub struct BootLoaderConfig { pub state: STATE, } -impl<'a, FLASH: NorFlash> +impl<'a, ActiveFlash: NorFlash, DFUFlash: NorFlash, StateFlash: NorFlash> BootLoaderConfig< - BlockingPartition<'a, NoopRawMutex, FLASH>, - BlockingPartition<'a, NoopRawMutex, FLASH>, - BlockingPartition<'a, NoopRawMutex, FLASH>, + BlockingPartition<'a, NoopRawMutex, ActiveFlash>, + BlockingPartition<'a, NoopRawMutex, DFUFlash>, + BlockingPartition<'a, NoopRawMutex, StateFlash>, > { /// Create a bootloader config from the flash and address symbols defined in the linkerfile // #[cfg(target_os = "none")] - pub fn from_linkerfile_blocking(flash: &'a Mutex>) -> Self { + pub fn from_linkerfile_blocking( + active_flash: &'a Mutex>, + dfu_flash: &'a Mutex>, + state_flash: &'a Mutex>, + ) -> Self { extern "C" { static __bootloader_state_start: u32; static __bootloader_state_end: u32; @@ -73,21 +77,21 @@ impl<'a, FLASH: NorFlash> let end = &__bootloader_active_end as *const u32 as u32; trace!("ACTIVE: 0x{:x} - 0x{:x}", start, end); - BlockingPartition::new(flash, start, end - start) + BlockingPartition::new(active_flash, start, end - start) }; let dfu = unsafe { let start = &__bootloader_dfu_start as *const u32 as u32; let end = &__bootloader_dfu_end as *const u32 as u32; trace!("DFU: 0x{:x} - 0x{:x}", start, end); - BlockingPartition::new(flash, start, end - start) + BlockingPartition::new(dfu_flash, start, end - start) }; let state = unsafe { let start = &__bootloader_state_start as *const u32 as u32; let end = &__bootloader_state_end as *const u32 as u32; trace!("STATE: 0x{:x} - 0x{:x}", start, end); - BlockingPartition::new(flash, start, end - start) + BlockingPartition::new(state_flash, start, end - start) }; Self { active, dfu, state } diff --git a/embassy-boot/src/firmware_updater/asynch.rs b/embassy-boot/src/firmware_updater/asynch.rs index 2e43e1cc1..5634b48d4 100644 --- a/embassy-boot/src/firmware_updater/asynch.rs +++ b/embassy-boot/src/firmware_updater/asynch.rs @@ -16,11 +16,14 @@ pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { } #[cfg(target_os = "none")] -impl<'a, FLASH: NorFlash> - FirmwareUpdaterConfig, Partition<'a, NoopRawMutex, FLASH>> +impl<'a, DFUFlash: NorFlash, StateFlash: NorFlash> + FirmwareUpdaterConfig, Partition<'a, NoopRawMutex, StateFlash>> { /// Create a firmware updater config from the flash and address symbols defined in the linkerfile - pub fn from_linkerfile(flash: &'a embassy_sync::mutex::Mutex) -> Self { + pub fn from_linkerfile( + dfu_flash: &'a embassy_sync::mutex::Mutex, + state_flash: &'a embassy_sync::mutex::Mutex, + ) -> Self { extern "C" { static __bootloader_state_start: u32; static __bootloader_state_end: u32; @@ -33,14 +36,14 @@ impl<'a, FLASH: NorFlash> let end = &__bootloader_dfu_end as *const u32 as u32; trace!("DFU: 0x{:x} - 0x{:x}", start, end); - Partition::new(flash, start, end - start) + Partition::new(dfu_flash, start, end - start) }; let state = unsafe { let start = &__bootloader_state_start as *const u32 as u32; let end = &__bootloader_state_end as *const u32 as u32; trace!("STATE: 0x{:x} - 0x{:x}", start, end); - Partition::new(flash, start, end - start) + Partition::new(state_flash, start, end - start) }; Self { dfu, state } diff --git a/embassy-boot/src/firmware_updater/blocking.rs b/embassy-boot/src/firmware_updater/blocking.rs index f1368540d..3814b6c31 100644 --- a/embassy-boot/src/firmware_updater/blocking.rs +++ b/embassy-boot/src/firmware_updater/blocking.rs @@ -16,12 +16,16 @@ pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { } #[cfg(target_os = "none")] -impl<'a, FLASH: NorFlash> - FirmwareUpdaterConfig, BlockingPartition<'a, NoopRawMutex, FLASH>> +impl<'a, DFUFlash: NorFlash, StateFlash: NorFlash> + FirmwareUpdaterConfig< + BlockingPartition<'a, NoopRawMutex, DFUFlash>, + BlockingPartition<'a, NoopRawMutex, StateFlash>, + > { /// Create a firmware updater config from the flash and address symbols defined in the linkerfile pub fn from_linkerfile_blocking( - flash: &'a embassy_sync::blocking_mutex::Mutex>, + dfu_flash: &'a embassy_sync::blocking_mutex::Mutex>, + state_flash: &'a embassy_sync::blocking_mutex::Mutex>, ) -> Self { extern "C" { static __bootloader_state_start: u32; @@ -35,14 +39,14 @@ impl<'a, FLASH: NorFlash> let end = &__bootloader_dfu_end as *const u32 as u32; trace!("DFU: 0x{:x} - 0x{:x}", start, end); - BlockingPartition::new(flash, start, end - start) + BlockingPartition::new(dfu_flash, start, end - start) }; let state = unsafe { let start = &__bootloader_state_start as *const u32 as u32; let end = &__bootloader_state_end as *const u32 as u32; trace!("STATE: 0x{:x} - 0x{:x}", start, end); - BlockingPartition::new(flash, start, end - start) + BlockingPartition::new(state_flash, start, end - start) }; Self { dfu, state } -- cgit From af2b4df833902fa8d42cb133c52733fe0b848bc7 Mon Sep 17 00:00:00 2001 From: Badr Bouslikhin Date: Wed, 7 Feb 2024 11:32:13 +0100 Subject: refactor(boot): change generics name to match existing convention --- embassy-boot/src/boot_loader.rs | 14 +++++++------- embassy-boot/src/firmware_updater/asynch.rs | 8 ++++---- embassy-boot/src/firmware_updater/blocking.rs | 11 ++++------- 3 files changed, 15 insertions(+), 18 deletions(-) (limited to 'embassy-boot/src') diff --git a/embassy-boot/src/boot_loader.rs b/embassy-boot/src/boot_loader.rs index 54ae8a34b..c433ce439 100644 --- a/embassy-boot/src/boot_loader.rs +++ b/embassy-boot/src/boot_loader.rs @@ -49,19 +49,19 @@ pub struct BootLoaderConfig { pub state: STATE, } -impl<'a, ActiveFlash: NorFlash, DFUFlash: NorFlash, StateFlash: NorFlash> +impl<'a, ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoaderConfig< - BlockingPartition<'a, NoopRawMutex, ActiveFlash>, - BlockingPartition<'a, NoopRawMutex, DFUFlash>, - BlockingPartition<'a, NoopRawMutex, StateFlash>, + BlockingPartition<'a, NoopRawMutex, ACTIVE>, + BlockingPartition<'a, NoopRawMutex, DFU>, + BlockingPartition<'a, NoopRawMutex, STATE>, > { /// Create a bootloader config from the flash and address symbols defined in the linkerfile // #[cfg(target_os = "none")] pub fn from_linkerfile_blocking( - active_flash: &'a Mutex>, - dfu_flash: &'a Mutex>, - state_flash: &'a Mutex>, + active_flash: &'a Mutex>, + dfu_flash: &'a Mutex>, + state_flash: &'a Mutex>, ) -> Self { extern "C" { static __bootloader_state_start: u32; diff --git a/embassy-boot/src/firmware_updater/asynch.rs b/embassy-boot/src/firmware_updater/asynch.rs index 5634b48d4..668f16f16 100644 --- a/embassy-boot/src/firmware_updater/asynch.rs +++ b/embassy-boot/src/firmware_updater/asynch.rs @@ -16,13 +16,13 @@ pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { } #[cfg(target_os = "none")] -impl<'a, DFUFlash: NorFlash, StateFlash: NorFlash> - FirmwareUpdaterConfig, Partition<'a, NoopRawMutex, StateFlash>> +impl<'a, DFU: NorFlash, STATE: NorFlash> + FirmwareUpdaterConfig, Partition<'a, NoopRawMutex, STATE>> { /// Create a firmware updater config from the flash and address symbols defined in the linkerfile pub fn from_linkerfile( - dfu_flash: &'a embassy_sync::mutex::Mutex, - state_flash: &'a embassy_sync::mutex::Mutex, + dfu_flash: &'a embassy_sync::mutex::Mutex, + state_flash: &'a embassy_sync::mutex::Mutex, ) -> Self { extern "C" { static __bootloader_state_start: u32; diff --git a/embassy-boot/src/firmware_updater/blocking.rs b/embassy-boot/src/firmware_updater/blocking.rs index 3814b6c31..cf850fce3 100644 --- a/embassy-boot/src/firmware_updater/blocking.rs +++ b/embassy-boot/src/firmware_updater/blocking.rs @@ -16,16 +16,13 @@ pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { } #[cfg(target_os = "none")] -impl<'a, DFUFlash: NorFlash, StateFlash: NorFlash> - FirmwareUpdaterConfig< - BlockingPartition<'a, NoopRawMutex, DFUFlash>, - BlockingPartition<'a, NoopRawMutex, StateFlash>, - > +impl<'a, DFU: NorFlash, STATE: NorFlash> + FirmwareUpdaterConfig, BlockingPartition<'a, NoopRawMutex, STATE>> { /// Create a firmware updater config from the flash and address symbols defined in the linkerfile pub fn from_linkerfile_blocking( - dfu_flash: &'a embassy_sync::blocking_mutex::Mutex>, - state_flash: &'a embassy_sync::blocking_mutex::Mutex>, + dfu_flash: &'a embassy_sync::blocking_mutex::Mutex>, + state_flash: &'a embassy_sync::blocking_mutex::Mutex>, ) -> Self { extern "C" { static __bootloader_state_start: u32; -- cgit From 634c409c55c71ca2871cd05d4a7754654926db48 Mon Sep 17 00:00:00 2001 From: Badr Bouslikhin Date: Wed, 7 Feb 2024 13:06:48 +0100 Subject: docs(boot): document from_linkerfile_blocking method --- embassy-boot/src/boot_loader.rs | 33 ++++++++++++++++++++++++++- embassy-boot/src/firmware_updater/blocking.rs | 32 +++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) (limited to 'embassy-boot/src') diff --git a/embassy-boot/src/boot_loader.rs b/embassy-boot/src/boot_loader.rs index c433ce439..2a5f024f6 100644 --- a/embassy-boot/src/boot_loader.rs +++ b/embassy-boot/src/boot_loader.rs @@ -56,7 +56,38 @@ impl<'a, ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BlockingPartition<'a, NoopRawMutex, STATE>, > { - /// Create a bootloader config from the flash and address symbols defined in the linkerfile + /// Constructs a `BootLoaderConfig` instance from flash memory and address symbols defined in the linker file. + /// + /// This method initializes `BlockingPartition` instances for the active, DFU (Device Firmware Update), + /// and state partitions, leveraging start and end addresses specified by the linker. These partitions + /// are critical for managing firmware updates, application state, and boot operations within the bootloader. + /// + /// # Parameters + /// - `active_flash`: A reference to a mutex-protected `RefCell` for the active partition's flash interface. + /// - `dfu_flash`: A reference to a mutex-protected `RefCell` for the DFU partition's flash interface. + /// - `state_flash`: A reference to a mutex-protected `RefCell` for the state partition's flash interface. + /// + /// # Safety + /// The method contains `unsafe` blocks for dereferencing raw pointers that represent the start and end addresses + /// of the bootloader's partitions in flash memory. It is crucial that these addresses are accurately defined + /// in the memory.x file to prevent undefined behavior. + /// + /// The caller must ensure that the memory regions defined by these symbols are valid and that the flash memory + /// interfaces provided are compatible with these regions. + /// + /// # Returns + /// A `BootLoaderConfig` instance with `BlockingPartition` instances for the active, DFU, and state partitions. + /// + /// # Example + /// ```no_run + /// // Assume `active_flash`, `dfu_flash`, and `state_flash` all share the same flash memory interface. + /// let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); + /// let flash = Mutex::new(RefCell::new(layout.bank1_region)); + /// + /// let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash); + /// // `config` can now be used to create a `BootLoader` instance for managing boot operations. + /// ``` + /// Working examples can be found in the bootloader examples folder. // #[cfg(target_os = "none")] pub fn from_linkerfile_blocking( active_flash: &'a Mutex>, diff --git a/embassy-boot/src/firmware_updater/blocking.rs b/embassy-boot/src/firmware_updater/blocking.rs index cf850fce3..a29efabf0 100644 --- a/embassy-boot/src/firmware_updater/blocking.rs +++ b/embassy-boot/src/firmware_updater/blocking.rs @@ -19,7 +19,37 @@ pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { impl<'a, DFU: NorFlash, STATE: NorFlash> FirmwareUpdaterConfig, BlockingPartition<'a, NoopRawMutex, STATE>> { - /// Create a firmware updater config from the flash and address symbols defined in the linkerfile + /// Constructs a `FirmwareUpdaterConfig` instance from flash memory and address symbols defined in the linker file. + /// + /// This method initializes `BlockingPartition` instances for the DFU (Device Firmware Update), and state + /// partitions, leveraging start and end addresses specified by the linker. These partitions are critical + /// for managing firmware updates, application state, and boot operations within the bootloader. + /// + /// # Parameters + /// - `dfu_flash`: A reference to a mutex-protected `RefCell` for the DFU partition's flash interface. + /// - `state_flash`: A reference to a mutex-protected `RefCell` for the state partition's flash interface. + /// + /// # Safety + /// The method contains `unsafe` blocks for dereferencing raw pointers that represent the start and end addresses + /// of the bootloader's partitions in flash memory. It is crucial that these addresses are accurately defined + /// in the memory.x file to prevent undefined behavior. + /// + /// The caller must ensure that the memory regions defined by these symbols are valid and that the flash memory + /// interfaces provided are compatible with these regions. + /// + /// # Returns + /// A `FirmwareUpdaterConfig` instance with `BlockingPartition` instances for the DFU, and state partitions. + /// + /// # Example + /// ```no_run + /// // Assume `dfu_flash`, and `state_flash` share the same flash memory interface. + /// let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); + /// let flash = Mutex::new(RefCell::new(layout.bank1_region)); + /// + /// let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash); + /// // `config` can now be used to create a `FirmwareUpdater` instance for managing boot operations. + /// ``` + /// Working examples can be found in the bootloader examples folder. pub fn from_linkerfile_blocking( dfu_flash: &'a embassy_sync::blocking_mutex::Mutex>, state_flash: &'a embassy_sync::blocking_mutex::Mutex>, -- cgit From e391b9b74c95090548c50b6f05a859f0220c42f9 Mon Sep 17 00:00:00 2001 From: Badr Bouslikhin Date: Wed, 7 Feb 2024 14:37:38 +0100 Subject: docs(boot): ignore partial non-compilable example in rustdoc --- embassy-boot/src/boot_loader.rs | 2 +- embassy-boot/src/firmware_updater/blocking.rs | 2 +- embassy-boot/src/firmware_updater/mod.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'embassy-boot/src') diff --git a/embassy-boot/src/boot_loader.rs b/embassy-boot/src/boot_loader.rs index 2a5f024f6..ca1a1b10c 100644 --- a/embassy-boot/src/boot_loader.rs +++ b/embassy-boot/src/boot_loader.rs @@ -79,7 +79,7 @@ impl<'a, ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> /// A `BootLoaderConfig` instance with `BlockingPartition` instances for the active, DFU, and state partitions. /// /// # Example - /// ```no_run + /// ```ignore /// // Assume `active_flash`, `dfu_flash`, and `state_flash` all share the same flash memory interface. /// let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); /// let flash = Mutex::new(RefCell::new(layout.bank1_region)); diff --git a/embassy-boot/src/firmware_updater/blocking.rs b/embassy-boot/src/firmware_updater/blocking.rs index a29efabf0..4044871f0 100644 --- a/embassy-boot/src/firmware_updater/blocking.rs +++ b/embassy-boot/src/firmware_updater/blocking.rs @@ -41,7 +41,7 @@ impl<'a, DFU: NorFlash, STATE: NorFlash> /// A `FirmwareUpdaterConfig` instance with `BlockingPartition` instances for the DFU, and state partitions. /// /// # Example - /// ```no_run + /// ```ignore /// // Assume `dfu_flash`, and `state_flash` share the same flash memory interface. /// let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); /// let flash = Mutex::new(RefCell::new(layout.bank1_region)); diff --git a/embassy-boot/src/firmware_updater/mod.rs b/embassy-boot/src/firmware_updater/mod.rs index 4814786bf..4c4f4f10b 100644 --- a/embassy-boot/src/firmware_updater/mod.rs +++ b/embassy-boot/src/firmware_updater/mod.rs @@ -8,7 +8,7 @@ use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind}; /// Firmware updater flash configuration holding the two flashes used by the updater /// /// If only a single flash is actually used, then that flash should be partitioned into two partitions before use. -/// The easiest way to do this is to use [`FirmwareUpdaterConfig::from_linkerfile`] or [`FirmwareUpdaterConfig::from_linkerfile_blocking`] which will partition +/// The easiest way to do this is to use [`FirmwareUpdaterConfig::from_linkerfile_blocking`] or [`FirmwareUpdaterConfig::from_linkerfile_blocking`] which will partition /// the provided flash according to symbols defined in the linkerfile. pub struct FirmwareUpdaterConfig { /// The dfu flash partition -- cgit