embassy-boot

Crates

0.1.1

Versions

default

Flavors

Struct BootLoader

Source
pub struct BootLoader { /* private fields */ }
Expand description

BootLoader works with any flash implementing embedded_storage and can also work with different page sizes and flash write sizes.

Implementations§

Source§

impl BootLoader

Source

pub fn new(active: Partition, dfu: Partition, state: Partition) -> Self

Create a new instance of a bootloader with the given partitions.

  • All partitions must be aligned with the PAGE_SIZE const generic parameter.
  • The dfu partition must be at least PAGE_SIZE bigger than the active partition.
Source

pub fn boot_address(&self) -> usize

Return the boot address for the active partition.

Source

pub fn prepare_boot<P: FlashConfig>( &mut self, p: &mut P, magic: &mut [u8], page: &mut [u8], ) -> Result<State, BootError>

Perform necessary boot preparations like swapping images.

The DFU partition is assumed to be 1 page bigger than the active partition for the swap algorithm to work correctly.

SWAPPING

Assume a flash size of 3 pages for the active partition, and 4 pages for the DFU partition. The swap index contains the copy progress, as to allow continuation of the copy process on power failure. The index counter is represented within 1 or more pages (depending on total flash size), where a page X is considered swapped if index at location (X + WRITE_SIZE) contains a zero value. This ensures that index updates can be performed atomically and avoid a situation where the wrong index value is set (page write size is “atomic”).

+———–+————+––––+––––+––––+––––+ | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | +———–+————+––––+––––+––––+––––+ | Active | 0 | 1 | 2 | 3 | - | | DFU | 0 | 3 | 2 | 1 | X | +———–+————+––––+––––+––––+––––+

The algorithm starts by copying ‘backwards’, and after the first step, the layout is as follows:

+———–+————+––––+––––+––––+––––+ | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | +———–+————+––––+––––+––––+––––+ | Active | 1 | 1 | 2 | 1 | - | | DFU | 1 | 3 | 2 | 1 | 3 | +———–+————+––––+––––+––––+––––+

The next iteration performs the same steps

+———–+————+––––+––––+––––+––––+ | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | +———–+————+––––+––––+––––+––––+ | Active | 2 | 1 | 2 | 1 | - | | DFU | 2 | 3 | 2 | 2 | 3 | +———–+————+––––+––––+––––+––––+

And again until we’re done

+———–+————+––––+––––+––––+––––+ | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | +———–+————+––––+––––+––––+––––+ | Active | 3 | 3 | 2 | 1 | - | | DFU | 3 | 3 | 1 | 2 | 3 | +———–+————+––––+––––+––––+––––+

REVERTING

The reverting algorithm uses the swap index to discover that images were swapped, but that the application failed to mark the boot successful. In this case, the revert algorithm will run.

The revert index is located separately from the swap index, to ensure that revert can continue on power failure.

The revert algorithm works forwards, by starting copying into the ‘unused’ DFU page at the start.

+———–+–––––––+––––+––––+––––+––––+ | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | +———–+–––––––+––––+––––+––––+––––+ | Active | 3 | 1 | 2 | 1 | - | | DFU | 3 | 3 | 1 | 2 | 3 | +———–+–––––––+––––+––––+––––+––––+

+———–+–––––––+––––+––––+––––+––––+ | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | +———–+–––––––+––––+––––+––––+––––+ | Active | 3 | 1 | 2 | 1 | - | | DFU | 3 | 3 | 2 | 2 | 3 | +———–+–––––––+––––+––––+––––+––––+

+———–+–––––––+––––+––––+––––+––––+ | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | +———–+–––––––+––––+––––+––––+––––+ | Active | 3 | 1 | 2 | 3 | - | | DFU | 3 | 3 | 2 | 1 | 3 | +———–+–––––––+––––+––––+––––+––––+

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.