aboutsummaryrefslogtreecommitdiff
path: root/embassy-boot
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-boot')
-rw-r--r--embassy-boot/rp/src/lib.rs69
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")]
4mod fmt; 4mod fmt;
5 5
6pub use embassy_boot::{AlignedBuffer, BootFlash, FirmwareUpdater, FlashConfig, Partition, SingleFlashConfig, State}; 6#[cfg(feature = "nightly")]
7pub use embassy_boot::FirmwareUpdater;
8pub use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State};
7use embassy_rp::flash::{Flash, ERASE_SIZE}; 9use embassy_rp::flash::{Flash, ERASE_SIZE};
8use embassy_rp::peripherals::{FLASH, WATCHDOG}; 10use embassy_rp::peripherals::{FLASH, WATCHDOG};
9use embassy_rp::watchdog::Watchdog; 11use embassy_rp::watchdog::Watchdog;
@@ -11,27 +13,28 @@ use embassy_time::Duration;
11use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; 13use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
12 14
13/// A bootloader for RP2040 devices. 15/// A bootloader for RP2040 devices.
14pub struct BootLoader<const BUFFER_SIZE: usize = ERASE_SIZE> { 16pub 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
19impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> { 21impl<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")]
55impl 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.
95pub struct WatchdogFlash<'d, const SIZE: usize> { 58pub struct WatchdogFlash<'d, const SIZE: usize> {
96 flash: Flash<'d, FLASH, SIZE>, 59 flash: Flash<'d, FLASH, SIZE>,