embassy-boot-stm32

Crates

git

Versions

default

Flavors

Skip to main content

BlockingFirmwareUpdater

Struct BlockingFirmwareUpdater 

Source
pub struct BlockingFirmwareUpdater<'d, DFU, STATE>
where DFU: NorFlash, STATE: NorFlash,
{ /* private fields */ }
Expand description

Blocking FirmwareUpdater is an application API for interacting with the BootLoader without the ability to ‘mess up’ the internal bootloader state

Implementations§

Source§

impl<'d, DFU, STATE> BlockingFirmwareUpdater<'d, DFU, STATE>
where DFU: NorFlash, STATE: NorFlash,

Source

pub fn new( config: FirmwareUpdaterConfig<DFU, STATE>, aligned: &'d mut [u8], ) -> BlockingFirmwareUpdater<'d, DFU, STATE>

Create a firmware updater instance with partition ranges for the update and state partitions.

§Safety

The aligned buffer must have a size of STATE::WRITE_SIZE, and follow the alignment rules for the flash being read from and written to.

Source

pub fn get_state(&mut self) -> Result<State, FirmwareUpdaterError>

Obtain the current state.

This is useful to check if the bootloader has just done a swap, in order to do verifications and self-tests of the new image before calling mark_booted.

Source

pub fn verify_and_mark_updated<D, V>( &mut self, public_key: &[u8], signature: &[u8], chunk_buf: &mut [u8], update_len: u32, ) -> Result<(), FirmwareUpdaterError>
where D: Digest, V: VerifyingKey,

Verify the DFU given a public key. If there is an error then DO NOT proceed with updating the firmware as it must be signed with a corresponding private key (otherwise it could be malicious firmware).

Mark to trigger firmware swap on next boot if verify succeeds.

The signature is expected to have been generated from the firmware bytes using a digest of the provided type.

§Buffer requirements

chunk_buf must be nonempty and satisfy the flash’s buffer alignment requirements. Reads start at zero and use full chunks, so its length must be a multiple of DFU::READ_SIZE and DFU must be readable through update_len rounded up to that length. Only 0..update_len is hashed. Flash read failures are returned as errors.

§Panics

Panics if chunk_buf is empty or update_len exceeds dfu capacity.

Source

pub fn hash<D>( &mut self, update_len: u32, chunk_buf: &mut [u8], ) -> Result<<D as Digest>::Output, FirmwareUpdaterError>
where D: Digest,

Compute a digest of the update in the DFU partition.

§Buffer requirements

chunk_buf must be nonempty and satisfy the flash’s buffer alignment requirements. Reads start at zero and use full chunks, so its length must be a multiple of DFU::READ_SIZE and DFU must be readable through update_len rounded up to that length. Only 0..update_len is hashed. Flash read failures are returned as errors.

§Panics

Panics if chunk_buf is empty.

Source

pub fn read_dfu( &mut self, offset: u32, buf: &mut [u8], ) -> Result<(), FirmwareUpdaterError>

Read a slice of data from the DFU storage peripheral, starting the read operation at the given address offset, and reading buf.len() bytes.

§Errors

Returns an error if the arguments are not aligned or out of bounds.

Source

pub fn mark_updated(&mut self) -> Result<(), FirmwareUpdaterError>

Mark to trigger firmware swap on next boot.

With signature support enabled, verify first or use a verifying bootloader.

Source

pub fn mark_dfu(&mut self) -> Result<(), FirmwareUpdaterError>

Mark to trigger USB DFU device on next boot.

Source

pub fn mark_booted(&mut self) -> Result<(), FirmwareUpdaterError>

Mark firmware boot successful and stop rollback on reset.

Source

pub fn write_firmware( &mut self, offset: usize, data: &[u8], ) -> Result<(), FirmwareUpdaterError>

Writes firmware data to the device.

This function writes the given data to the firmware area starting at the specified offset. It handles sector erasures and data writes while verifying the device is in a proper state for firmware updates. The function ensures that only unerased sectors are erased before writing and efficiently handles the writing process across sector boundaries and in various configurations (data size, sector size, etc.).

§Arguments
  • offset - The starting offset within the firmware area where data writing should begin.
  • data - A slice of bytes representing the firmware data to be written. It must be a multiple of NorFlash WRITE_SIZE.
§Returns

A Result<(), FirmwareUpdaterError> indicating the success or failure of the write operation.

§Errors

This function will return an error if:

  • The device is not in a proper state to receive firmware updates (e.g., not booted).
  • There is a failure erasing a sector before writing.
  • There is a failure writing data to the device.
Source

pub fn prepare_update(&mut self) -> Result<&mut DFU, FirmwareUpdaterError>

Prepare for an incoming DFU update by erasing the entire DFU area and returning its Partition.

Using this instead of write_firmware allows for an optimized API in exchange for added complexity.

Auto Trait Implementations§

§

impl<'d, DFU, STATE> !UnwindSafe for BlockingFirmwareUpdater<'d, DFU, STATE>

§

impl<'d, DFU, STATE> Freeze for BlockingFirmwareUpdater<'d, DFU, STATE>
where DFU: Freeze, BlockingFirmwareState<'d, STATE>: Freeze,

§

impl<'d, DFU, STATE> RefUnwindSafe for BlockingFirmwareUpdater<'d, DFU, STATE>

§

impl<'d, DFU, STATE> Send for BlockingFirmwareUpdater<'d, DFU, STATE>
where DFU: Send, BlockingFirmwareState<'d, STATE>: Send,

§

impl<'d, DFU, STATE> Sync for BlockingFirmwareUpdater<'d, DFU, STATE>
where DFU: Sync, BlockingFirmwareState<'d, STATE>: Sync,

§

impl<'d, DFU, STATE> Unpin for BlockingFirmwareUpdater<'d, DFU, STATE>
where DFU: Unpin, BlockingFirmwareState<'d, STATE>: Unpin,

§

impl<'d, DFU, STATE> UnsafeUnpin for BlockingFirmwareUpdater<'d, DFU, STATE>

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 = !

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.