aboutsummaryrefslogtreecommitdiff
path: root/embassy-boot
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2023-08-11 19:47:24 +0200
committerUlf Lilleengen <[email protected]>2023-08-11 20:58:31 +0200
commit55ff397c0cde8a04c41cfc228645c3fd33383cd1 (patch)
treeb73e5fee9027422cb121b892e6d467fd0f73cfe7 /embassy-boot
parentc1da2c0219667085124c47d8059ffbf077adaf9d (diff)
boot: release flash after prepare and refactor api
This refactoring of the chip specific bootloader creates the internal boot instance and aligned buffer in the prepare stage, so that they are automatically dropped after. This unlocks a use case where peripherals owning the flash need to be Drop'ed before load() happens.
Diffstat (limited to 'embassy-boot')
-rw-r--r--embassy-boot/nrf/src/lib.rs37
-rw-r--r--embassy-boot/rp/src/lib.rs33
-rw-r--r--embassy-boot/stm32/src/lib.rs33
3 files changed, 32 insertions, 71 deletions
diff --git a/embassy-boot/nrf/src/lib.rs b/embassy-boot/nrf/src/lib.rs
index df94819fc..b9d86eb17 100644
--- a/embassy-boot/nrf/src/lib.rs
+++ b/embassy-boot/nrf/src/lib.rs
@@ -14,28 +14,17 @@ use embassy_nrf::wdt;
14use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; 14use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
15 15
16/// A bootloader for nRF devices. 16/// A bootloader for nRF devices.
17pub struct BootLoader<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize = PAGE_SIZE> { 17pub struct BootLoader<const BUFFER_SIZE: usize = PAGE_SIZE>;
18 boot: embassy_boot::BootLoader<ACTIVE, DFU, STATE>, 18
19 aligned_buf: AlignedBuffer<BUFFER_SIZE>, 19impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> {
20} 20 /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware.
21 21 pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>(
22impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize> 22 config: BootLoaderConfig<ACTIVE, DFU, STATE>,
23 BootLoader<ACTIVE, DFU, STATE, BUFFER_SIZE> 23 ) -> Self {
24{ 24 let mut aligned_buf = AlignedBuffer([0; BUFFER_SIZE]);
25 /// Create a new bootloader instance using the supplied partitions for active, dfu and state. 25 let mut boot = embassy_boot::BootLoader::new(config);
26 pub fn new(config: BootLoaderConfig<ACTIVE, DFU, STATE>) -> Self { 26 boot.prepare_boot(&mut aligned_buf.0).expect("Boot prepare error");
27 Self { 27 Self
28 boot: embassy_boot::BootLoader::new(config),
29 aligned_buf: AlignedBuffer([0; BUFFER_SIZE]),
30 }
31 }
32
33 /// Inspect the bootloader state and perform actions required before booting, such as swapping
34 /// firmware.
35 pub fn prepare(&mut self) {
36 self.boot
37 .prepare_boot(&mut self.aligned_buf.0)
38 .expect("Boot prepare error");
39 } 28 }
40 29
41 /// Boots the application without softdevice mechanisms. 30 /// Boots the application without softdevice mechanisms.
@@ -45,8 +34,6 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
45 /// This modifies the stack pointer and reset vector and will run code placed in the active partition. 34 /// This modifies the stack pointer and reset vector and will run code placed in the active partition.
46 #[cfg(not(feature = "softdevice"))] 35 #[cfg(not(feature = "softdevice"))]
47 pub unsafe fn load(self, start: u32) -> ! { 36 pub unsafe fn load(self, start: u32) -> ! {
48 core::mem::drop(self.boot);
49
50 let mut p = cortex_m::Peripherals::steal(); 37 let mut p = cortex_m::Peripherals::steal();
51 p.SCB.invalidate_icache(); 38 p.SCB.invalidate_icache();
52 p.SCB.vtor.write(start); 39 p.SCB.vtor.write(start);
@@ -59,7 +46,7 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
59 /// 46 ///
60 /// This modifies the stack pointer and reset vector and will run code placed in the active partition. 47 /// This modifies the stack pointer and reset vector and will run code placed in the active partition.
61 #[cfg(feature = "softdevice")] 48 #[cfg(feature = "softdevice")]
62 pub unsafe fn load(&mut self, _app: u32) -> ! { 49 pub unsafe fn load(self, _app: u32) -> ! {
63 use nrf_softdevice_mbr as mbr; 50 use nrf_softdevice_mbr as mbr;
64 const NRF_SUCCESS: u32 = 0; 51 const NRF_SUCCESS: u32 = 0;
65 52
diff --git a/embassy-boot/rp/src/lib.rs b/embassy-boot/rp/src/lib.rs
index f5aefa416..96bcf3bf7 100644
--- a/embassy-boot/rp/src/lib.rs
+++ b/embassy-boot/rp/src/lib.rs
@@ -15,28 +15,17 @@ use embassy_time::Duration;
15use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; 15use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
16 16
17/// A bootloader for RP2040 devices. 17/// A bootloader for RP2040 devices.
18pub struct BootLoader<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize = ERASE_SIZE> { 18pub struct BootLoader<const BUFFER_SIZE: usize = ERASE_SIZE>;
19 boot: embassy_boot::BootLoader<ACTIVE, DFU, STATE>,
20 aligned_buf: AlignedBuffer<BUFFER_SIZE>,
21}
22
23impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
24 BootLoader<ACTIVE, DFU, STATE, BUFFER_SIZE>
25{
26 /// Create a new bootloader instance using the supplied partitions for active, dfu and state.
27 pub fn new(config: BootLoaderConfig<ACTIVE, DFU, STATE>) -> Self {
28 Self {
29 boot: embassy_boot::BootLoader::new(config),
30 aligned_buf: AlignedBuffer([0; BUFFER_SIZE]),
31 }
32 }
33 19
34 /// Inspect the bootloader state and perform actions required before booting, such as swapping 20impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> {
35 /// firmware. 21 /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware
36 pub fn prepare(&mut self) { 22 pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>(
37 self.boot 23 config: BootLoaderConfig<ACTIVE, DFU, STATE>,
38 .prepare_boot(self.aligned_buf.as_mut()) 24 ) -> Self {
39 .expect("Boot prepare error"); 25 let mut aligned_buf = AlignedBuffer([0; BUFFER_SIZE]);
26 let mut boot = embassy_boot::BootLoader::new(config);
27 boot.prepare_boot(aligned_buf.as_mut()).expect("Boot prepare error");
28 Self
40 } 29 }
41 30
42 /// Boots the application. 31 /// Boots the application.
@@ -45,8 +34,6 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
45 /// 34 ///
46 /// This modifies the stack pointer and reset vector and will run code placed in the active partition. 35 /// This modifies the stack pointer and reset vector and will run code placed in the active partition.
47 pub unsafe fn load(self, start: u32) -> ! { 36 pub unsafe fn load(self, start: u32) -> ! {
48 core::mem::drop(self.boot);
49
50 trace!("Loading app at 0x{:x}", start); 37 trace!("Loading app at 0x{:x}", start);
51 #[allow(unused_mut)] 38 #[allow(unused_mut)]
52 let mut p = cortex_m::Peripherals::steal(); 39 let mut p = cortex_m::Peripherals::steal();
diff --git a/embassy-boot/stm32/src/lib.rs b/embassy-boot/stm32/src/lib.rs
index 25f029423..c6350c495 100644
--- a/embassy-boot/stm32/src/lib.rs
+++ b/embassy-boot/stm32/src/lib.rs
@@ -11,28 +11,17 @@ pub use embassy_boot::{FirmwareState, FirmwareUpdater};
11use embedded_storage::nor_flash::NorFlash; 11use embedded_storage::nor_flash::NorFlash;
12 12
13/// A bootloader for STM32 devices. 13/// A bootloader for STM32 devices.
14pub struct BootLoader<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize> { 14pub struct BootLoader;
15 boot: embassy_boot::BootLoader<ACTIVE, DFU, STATE>,
16 aligned_buf: AlignedBuffer<BUFFER_SIZE>,
17}
18
19impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
20 BootLoader<ACTIVE, DFU, STATE, BUFFER_SIZE>
21{
22 /// Create a new bootloader instance using the supplied partitions for active, dfu and state.
23 pub fn new(config: BootLoaderConfig<ACTIVE, DFU, STATE>) -> Self {
24 Self {
25 boot: embassy_boot::BootLoader::new(config),
26 aligned_buf: AlignedBuffer([0; BUFFER_SIZE]),
27 }
28 }
29 15
30 /// Inspect the bootloader state and perform actions required before booting, such as swapping 16impl BootLoader {
31 /// firmware. 17 /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware
32 pub fn prepare(&mut self) { 18 pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>(
33 self.boot 19 config: BootLoaderConfig<ACTIVE, DFU, STATE>,
34 .prepare_boot(self.aligned_buf.as_mut()) 20 ) -> Self {
35 .expect("Boot prepare error"); 21 let mut aligned_buf = AlignedBuffer([0; BUFFER_SIZE]);
22 let mut boot = embassy_boot::BootLoader::new(config);
23 boot.prepare_boot(aligned_buf.as_mut()).expect("Boot prepare error");
24 Self
36 } 25 }
37 26
38 /// Boots the application. 27 /// Boots the application.
@@ -41,8 +30,6 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
41 /// 30 ///
42 /// This modifies the stack pointer and reset vector and will run code placed in the active partition. 31 /// This modifies the stack pointer and reset vector and will run code placed in the active partition.
43 pub unsafe fn load(self, start: u32) -> ! { 32 pub unsafe fn load(self, start: u32) -> ! {
44 core::mem::drop(self.boot);
45
46 trace!("Loading app at 0x{:x}", start); 33 trace!("Loading app at 0x{:x}", start);
47 #[allow(unused_mut)] 34 #[allow(unused_mut)]
48 let mut p = cortex_m::Peripherals::steal(); 35 let mut p = cortex_m::Peripherals::steal();