diff options
| author | Ulf Lilleengen <[email protected]> | 2024-09-18 16:14:53 +0200 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2024-09-19 09:16:19 +0200 |
| commit | b1897c58fa617dbab02b39e7f5e399ed1c9d54b4 (patch) | |
| tree | 3931ee8d87810f3baa6ec72913123f9e250e531b /embassy-boot | |
| parent | 45cbcb513dc0bbf3e12c102df0db8c15643cc78b (diff) | |
Add revert state in embassy-boot
The revert state signals that a firmware revert has taken place,
allowing the application to know if a firmware update attempt was
reverted.
Diffstat (limited to 'embassy-boot')
| -rw-r--r-- | embassy-boot/src/boot_loader.rs | 6 | ||||
| -rw-r--r-- | embassy-boot/src/firmware_updater/asynch.rs | 3 | ||||
| -rw-r--r-- | embassy-boot/src/firmware_updater/blocking.rs | 3 | ||||
| -rw-r--r-- | embassy-boot/src/lib.rs | 6 |
4 files changed, 14 insertions, 4 deletions
diff --git a/embassy-boot/src/boot_loader.rs b/embassy-boot/src/boot_loader.rs index 61d61b96e..5bffdc5ea 100644 --- a/embassy-boot/src/boot_loader.rs +++ b/embassy-boot/src/boot_loader.rs | |||
| @@ -5,7 +5,7 @@ use embassy_sync::blocking_mutex::raw::NoopRawMutex; | |||
| 5 | use embassy_sync::blocking_mutex::Mutex; | 5 | use embassy_sync::blocking_mutex::Mutex; |
| 6 | use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind}; | 6 | use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind}; |
| 7 | 7 | ||
| 8 | use crate::{State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERASE_VALUE, SWAP_MAGIC}; | 8 | use crate::{State, DFU_DETACH_MAGIC, REVERT_MAGIC, STATE_ERASE_VALUE, SWAP_MAGIC}; |
| 9 | 9 | ||
| 10 | /// Errors returned by bootloader | 10 | /// Errors returned by bootloader |
| 11 | #[derive(PartialEq, Eq, Debug)] | 11 | #[derive(PartialEq, Eq, Debug)] |
| @@ -276,7 +276,7 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S | |||
| 276 | self.state.erase(0, self.state.capacity() as u32)?; | 276 | self.state.erase(0, self.state.capacity() as u32)?; |
| 277 | 277 | ||
| 278 | // Set magic | 278 | // Set magic |
| 279 | state_word.fill(BOOT_MAGIC); | 279 | state_word.fill(REVERT_MAGIC); |
| 280 | self.state.write(0, state_word)?; | 280 | self.state.write(0, state_word)?; |
| 281 | } | 281 | } |
| 282 | } | 282 | } |
| @@ -411,6 +411,8 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S | |||
| 411 | Ok(State::Swap) | 411 | Ok(State::Swap) |
| 412 | } else if !state_word.iter().any(|&b| b != DFU_DETACH_MAGIC) { | 412 | } else if !state_word.iter().any(|&b| b != DFU_DETACH_MAGIC) { |
| 413 | Ok(State::DfuDetach) | 413 | Ok(State::DfuDetach) |
| 414 | } else if !state_word.iter().any(|&b| b != REVERT_MAGIC) { | ||
| 415 | Ok(State::Revert) | ||
| 414 | } else { | 416 | } else { |
| 415 | Ok(State::Boot) | 417 | Ok(State::Boot) |
| 416 | } | 418 | } |
diff --git a/embassy-boot/src/firmware_updater/asynch.rs b/embassy-boot/src/firmware_updater/asynch.rs index 86b441592..b23857e2f 100644 --- a/embassy-boot/src/firmware_updater/asynch.rs +++ b/embassy-boot/src/firmware_updater/asynch.rs | |||
| @@ -289,7 +289,8 @@ impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> { | |||
| 289 | 289 | ||
| 290 | // Make sure we are running a booted firmware to avoid reverting to a bad state. | 290 | // Make sure we are running a booted firmware to avoid reverting to a bad state. |
| 291 | async fn verify_booted(&mut self) -> Result<(), FirmwareUpdaterError> { | 291 | async fn verify_booted(&mut self) -> Result<(), FirmwareUpdaterError> { |
| 292 | if self.get_state().await? == State::Boot { | 292 | let state = self.get_state().await?; |
| 293 | if state == State::Boot || state == State::DfuDetach || state == State::Revert { | ||
| 293 | Ok(()) | 294 | Ok(()) |
| 294 | } else { | 295 | } else { |
| 295 | Err(FirmwareUpdaterError::BadState) | 296 | Err(FirmwareUpdaterError::BadState) |
diff --git a/embassy-boot/src/firmware_updater/blocking.rs b/embassy-boot/src/firmware_updater/blocking.rs index d3c723456..5f64b4be9 100644 --- a/embassy-boot/src/firmware_updater/blocking.rs +++ b/embassy-boot/src/firmware_updater/blocking.rs | |||
| @@ -324,7 +324,8 @@ impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> { | |||
| 324 | 324 | ||
| 325 | // Make sure we are running a booted firmware to avoid reverting to a bad state. | 325 | // Make sure we are running a booted firmware to avoid reverting to a bad state. |
| 326 | fn verify_booted(&mut self) -> Result<(), FirmwareUpdaterError> { | 326 | fn verify_booted(&mut self) -> Result<(), FirmwareUpdaterError> { |
| 327 | if self.get_state()? == State::Boot || self.get_state()? == State::DfuDetach { | 327 | let state = self.get_state()?; |
| 328 | if state == State::Boot || state == State::DfuDetach || state == State::Revert { | ||
| 328 | Ok(()) | 329 | Ok(()) |
| 329 | } else { | 330 | } else { |
| 330 | Err(FirmwareUpdaterError::BadState) | 331 | Err(FirmwareUpdaterError::BadState) |
diff --git a/embassy-boot/src/lib.rs b/embassy-boot/src/lib.rs index 8849055e8..7d5cc58f9 100644 --- a/embassy-boot/src/lib.rs +++ b/embassy-boot/src/lib.rs | |||
| @@ -25,6 +25,7 @@ pub use firmware_updater::{ | |||
| 25 | FirmwareUpdaterError, | 25 | FirmwareUpdaterError, |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | pub(crate) const REVERT_MAGIC: u8 = 0xC0; | ||
| 28 | pub(crate) const BOOT_MAGIC: u8 = 0xD0; | 29 | pub(crate) const BOOT_MAGIC: u8 = 0xD0; |
| 29 | pub(crate) const SWAP_MAGIC: u8 = 0xF0; | 30 | pub(crate) const SWAP_MAGIC: u8 = 0xF0; |
| 30 | pub(crate) const DFU_DETACH_MAGIC: u8 = 0xE0; | 31 | pub(crate) const DFU_DETACH_MAGIC: u8 = 0xE0; |
| @@ -37,6 +38,8 @@ pub enum State { | |||
| 37 | Boot, | 38 | Boot, |
| 38 | /// Bootloader has swapped the active partition with the dfu partition and will attempt boot. | 39 | /// Bootloader has swapped the active partition with the dfu partition and will attempt boot. |
| 39 | Swap, | 40 | Swap, |
| 41 | /// Bootloader has reverted the active partition with the dfu partition and will attempt boot. | ||
| 42 | Revert, | ||
| 40 | /// Application has received a request to reboot into DFU mode to apply an update. | 43 | /// Application has received a request to reboot into DFU mode to apply an update. |
| 41 | DfuDetach, | 44 | DfuDetach, |
| 42 | } | 45 | } |
| @@ -157,6 +160,9 @@ mod tests { | |||
| 157 | // Running again should cause a revert | 160 | // Running again should cause a revert |
| 158 | assert_eq!(State::Swap, bootloader.prepare_boot(&mut page).unwrap()); | 161 | assert_eq!(State::Swap, bootloader.prepare_boot(&mut page).unwrap()); |
| 159 | 162 | ||
| 163 | // Next time we know it was reverted | ||
| 164 | assert_eq!(State::Revert, bootloader.prepare_boot(&mut page).unwrap()); | ||
| 165 | |||
| 160 | let mut read_buf = [0; FIRMWARE_SIZE]; | 166 | let mut read_buf = [0; FIRMWARE_SIZE]; |
| 161 | flash.active().read(0, &mut read_buf).unwrap(); | 167 | flash.active().read(0, &mut read_buf).unwrap(); |
| 162 | assert_eq!(ORIGINAL, read_buf); | 168 | assert_eq!(ORIGINAL, read_buf); |
