diff options
| author | Rasmus Melchior Jacobsen <[email protected]> | 2023-05-30 13:57:03 +0200 |
|---|---|---|
| committer | Rasmus Melchior Jacobsen <[email protected]> | 2023-05-30 13:57:03 +0200 |
| commit | 24dee870a862d16fa2dc9be13d3f10dc3941b54b (patch) | |
| tree | f03ac373b0a3844567304beb4cbf7a02374be8c2 | |
| parent | 54bbb4400d02e40d142d3f2cd9186c7892374d83 (diff) | |
Align rp
| -rw-r--r-- | embassy-boot/rp/src/lib.rs | 69 |
1 files changed, 16 insertions, 53 deletions
diff --git a/embassy-boot/rp/src/lib.rs b/embassy-boot/rp/src/lib.rs index fb9bc3242..e825a7d13 100644 --- a/embassy-boot/rp/src/lib.rs +++ b/embassy-boot/rp/src/lib.rs | |||
| @@ -3,7 +3,9 @@ | |||
| 3 | #![doc = include_str!("../README.md")] | 3 | #![doc = include_str!("../README.md")] |
| 4 | mod fmt; | 4 | mod fmt; |
| 5 | 5 | ||
| 6 | pub use embassy_boot::{AlignedBuffer, BootFlash, FirmwareUpdater, FlashConfig, Partition, SingleFlashConfig, State}; | 6 | #[cfg(feature = "nightly")] |
| 7 | pub use embassy_boot::FirmwareUpdater; | ||
| 8 | pub use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State}; | ||
| 7 | use embassy_rp::flash::{Flash, ERASE_SIZE}; | 9 | use embassy_rp::flash::{Flash, ERASE_SIZE}; |
| 8 | use embassy_rp::peripherals::{FLASH, WATCHDOG}; | 10 | use embassy_rp::peripherals::{FLASH, WATCHDOG}; |
| 9 | use embassy_rp::watchdog::Watchdog; | 11 | use embassy_rp::watchdog::Watchdog; |
| @@ -11,27 +13,28 @@ use embassy_time::Duration; | |||
| 11 | use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; | 13 | use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; |
| 12 | 14 | ||
| 13 | /// A bootloader for RP2040 devices. | 15 | /// A bootloader for RP2040 devices. |
| 14 | pub struct BootLoader<const BUFFER_SIZE: usize = ERASE_SIZE> { | 16 | pub struct BootLoader<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize = ERASE_SIZE> { |
| 15 | boot: embassy_boot::BootLoader, | 17 | boot: embassy_boot::BootLoader<ACTIVE, DFU, STATE>, |
| 16 | aligned_buf: AlignedBuffer<BUFFER_SIZE>, | 18 | aligned_buf: AlignedBuffer<BUFFER_SIZE>, |
| 17 | } | 19 | } |
| 18 | 20 | ||
| 19 | impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> { | 21 | impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize> |
| 22 | BootLoader<ACTIVE, DFU, STATE, BUFFER_SIZE> | ||
| 23 | { | ||
| 20 | /// Create a new bootloader instance using the supplied partitions for active, dfu and state. | 24 | /// Create a new bootloader instance using the supplied partitions for active, dfu and state. |
| 21 | pub fn new(active: Partition, dfu: Partition, state: Partition) -> Self { | 25 | pub fn new(config: BootLoaderConfig<ACTIVE, DFU, STATE>) -> Self { |
| 22 | Self { | 26 | Self { |
| 23 | boot: embassy_boot::BootLoader::new(active, dfu, state), | 27 | boot: embassy_boot::BootLoader::new(config), |
| 24 | aligned_buf: AlignedBuffer([0; BUFFER_SIZE]), | 28 | aligned_buf: AlignedBuffer([0; BUFFER_SIZE]), |
| 25 | } | 29 | } |
| 26 | } | 30 | } |
| 27 | 31 | ||
| 28 | /// Inspect the bootloader state and perform actions required before booting, such as swapping | 32 | /// Inspect the bootloader state and perform actions required before booting, such as swapping |
| 29 | /// firmware. | 33 | /// firmware. |
| 30 | pub fn prepare<F: FlashConfig>(&mut self, flash: &mut F) -> usize { | 34 | pub fn prepare(&mut self) { |
| 31 | match self.boot.prepare_boot(flash, self.aligned_buf.as_mut()) { | 35 | self.boot |
| 32 | Ok(_) => embassy_rp::flash::FLASH_BASE + self.boot.boot_address(), | 36 | .prepare_boot(self.aligned_buf.as_mut()) |
| 33 | Err(_) => panic!("boot prepare error!"), | 37 | .expect("Boot prepare error"); |
| 34 | } | ||
| 35 | } | 38 | } |
| 36 | 39 | ||
| 37 | /// Boots the application. | 40 | /// Boots the application. |
| @@ -39,58 +42,18 @@ impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> { | |||
| 39 | /// # Safety | 42 | /// # Safety |
| 40 | /// | 43 | /// |
| 41 | /// This modifies the stack pointer and reset vector and will run code placed in the active partition. | 44 | /// This modifies the stack pointer and reset vector and will run code placed in the active partition. |
| 42 | pub unsafe fn load(&mut self, start: usize) -> ! { | 45 | pub unsafe fn load(&mut self, start: u32) -> ! { |
| 43 | trace!("Loading app at 0x{:x}", start); | 46 | trace!("Loading app at 0x{:x}", start); |
| 44 | #[allow(unused_mut)] | 47 | #[allow(unused_mut)] |
| 45 | let mut p = cortex_m::Peripherals::steal(); | 48 | let mut p = cortex_m::Peripherals::steal(); |
| 46 | #[cfg(not(armv6m))] | 49 | #[cfg(not(armv6m))] |
| 47 | p.SCB.invalidate_icache(); | 50 | p.SCB.invalidate_icache(); |
| 48 | p.SCB.vtor.write(start as u32); | 51 | p.SCB.vtor.write(start); |
| 49 | 52 | ||
| 50 | cortex_m::asm::bootload(start as *const u32) | 53 | cortex_m::asm::bootload(start as *const u32) |
| 51 | } | 54 | } |
| 52 | } | 55 | } |
| 53 | 56 | ||
| 54 | #[cfg(target_os = "none")] | ||
| 55 | impl Default for BootLoader<ERASE_SIZE> { | ||
| 56 | /// Create a new bootloader instance using parameters from linker script | ||
| 57 | fn default() -> Self { | ||
| 58 | extern "C" { | ||
| 59 | static __bootloader_state_start: u32; | ||
| 60 | static __bootloader_state_end: u32; | ||
| 61 | static __bootloader_active_start: u32; | ||
| 62 | static __bootloader_active_end: u32; | ||
| 63 | static __bootloader_dfu_start: u32; | ||
| 64 | static __bootloader_dfu_end: u32; | ||
| 65 | } | ||
| 66 | |||
| 67 | let active = unsafe { | ||
| 68 | Partition::new( | ||
| 69 | &__bootloader_active_start as *const u32 as u32, | ||
| 70 | &__bootloader_active_end as *const u32 as u32, | ||
| 71 | ) | ||
| 72 | }; | ||
| 73 | let dfu = unsafe { | ||
| 74 | Partition::new( | ||
| 75 | &__bootloader_dfu_start as *const u32 as u32, | ||
| 76 | &__bootloader_dfu_end as *const u32 as u32, | ||
| 77 | ) | ||
| 78 | }; | ||
| 79 | let state = unsafe { | ||
| 80 | Partition::new( | ||
| 81 | &__bootloader_state_start as *const u32 as u32, | ||
| 82 | &__bootloader_state_end as *const u32 as u32, | ||
| 83 | ) | ||
| 84 | }; | ||
| 85 | |||
| 86 | trace!("ACTIVE: 0x{:x} - 0x{:x}", active.from, active.to); | ||
| 87 | trace!("DFU: 0x{:x} - 0x{:x}", dfu.from, dfu.to); | ||
| 88 | trace!("STATE: 0x{:x} - 0x{:x}", state.from, state.to); | ||
| 89 | |||
| 90 | Self::new(active, dfu, state) | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | /// A flash implementation that will feed a watchdog when touching flash. | 57 | /// A flash implementation that will feed a watchdog when touching flash. |
| 95 | pub struct WatchdogFlash<'d, const SIZE: usize> { | 58 | pub struct WatchdogFlash<'d, const SIZE: usize> { |
| 96 | flash: Flash<'d, FLASH, SIZE>, | 59 | flash: Flash<'d, FLASH, SIZE>, |
