Add get_state helpers to allow self-testing before calling mark_booted
This commit is contained in:
parent
7f16b1cd23
commit
b2a327a858
@ -604,6 +604,21 @@ impl FirmwareUpdater {
|
|||||||
self.dfu.len()
|
self.dfu.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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`.
|
||||||
|
pub async fn get_state<F: AsyncNorFlash>(&mut self, flash: &mut F, aligned: &mut [u8]) -> Result<State, F::Error> {
|
||||||
|
flash.read(self.state.from as u32, aligned).await?;
|
||||||
|
|
||||||
|
if !aligned.iter().any(|&b| b != SWAP_MAGIC) {
|
||||||
|
Ok(State::Swap)
|
||||||
|
} else {
|
||||||
|
Ok(State::Boot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Mark to trigger firmware swap on next boot.
|
/// Mark to trigger firmware swap on next boot.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -673,8 +688,8 @@ impl FirmwareUpdater {
|
|||||||
self.dfu.from + offset + data.len()
|
self.dfu.from + offset + data.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
FirmwareWriter(self)
|
FirmwareWriter(self.dfu)
|
||||||
.write_firmware(offset, data, flash, block_size)
|
.write_block(offset, data, flash, block_size)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -690,13 +705,28 @@ impl FirmwareUpdater {
|
|||||||
|
|
||||||
trace!("Erased from {} to {}", self.dfu.from, self.dfu.to);
|
trace!("Erased from {} to {}", self.dfu.from, self.dfu.to);
|
||||||
|
|
||||||
Ok(FirmwareWriter(self))
|
Ok(FirmwareWriter(self.dfu))
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Blocking API
|
// Blocking API
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/// 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`.
|
||||||
|
pub fn get_state_blocking<F: NorFlash>(&mut self, flash: &mut F, aligned: &mut [u8]) -> Result<State, F::Error> {
|
||||||
|
flash.read(self.state.from as u32, aligned)?;
|
||||||
|
|
||||||
|
if !aligned.iter().any(|&b| b != SWAP_MAGIC) {
|
||||||
|
Ok(State::Swap)
|
||||||
|
} else {
|
||||||
|
Ok(State::Boot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Mark to trigger firmware swap on next boot.
|
/// Mark to trigger firmware swap on next boot.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -764,7 +794,7 @@ impl FirmwareUpdater {
|
|||||||
self.dfu.from + offset + data.len()
|
self.dfu.from + offset + data.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
FirmwareWriter(self).write_firmware_blocking(offset, data, flash, block_size)?;
|
FirmwareWriter(self.dfu).write_block_blocking(offset, data, flash, block_size)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -779,14 +809,14 @@ impl FirmwareUpdater {
|
|||||||
|
|
||||||
trace!("Erased from {} to {}", self.dfu.from, self.dfu.to);
|
trace!("Erased from {} to {}", self.dfu.from, self.dfu.to);
|
||||||
|
|
||||||
Ok(FirmwareWriter(self))
|
Ok(FirmwareWriter(self.dfu))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FirmwareWriter allows writing blocks to an already erased flash.
|
/// FirmwareWriter allows writing blocks to an already erased flash.
|
||||||
pub struct FirmwareWriter<'a>(&'a mut FirmwareUpdater);
|
pub struct FirmwareWriter(Partition);
|
||||||
|
|
||||||
impl<'a> FirmwareWriter<'a> {
|
impl FirmwareWriter {
|
||||||
/// Write data to a flash page.
|
/// Write data to a flash page.
|
||||||
///
|
///
|
||||||
/// The buffer must follow alignment requirements of the target flash and a multiple of page size big.
|
/// The buffer must follow alignment requirements of the target flash and a multiple of page size big.
|
||||||
@ -794,7 +824,7 @@ impl<'a> FirmwareWriter<'a> {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Failing to meet alignment and size requirements may result in a panic.
|
/// Failing to meet alignment and size requirements may result in a panic.
|
||||||
pub async fn write_firmware<F: AsyncNorFlash>(
|
pub async fn write_block<F: AsyncNorFlash>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
@ -803,11 +833,11 @@ impl<'a> FirmwareWriter<'a> {
|
|||||||
) -> Result<(), F::Error> {
|
) -> Result<(), F::Error> {
|
||||||
trace!(
|
trace!(
|
||||||
"Writing firmware at offset 0x{:x} len {}",
|
"Writing firmware at offset 0x{:x} len {}",
|
||||||
self.0.dfu.from + offset,
|
self.0.from + offset,
|
||||||
data.len()
|
data.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut write_offset = self.0.dfu.from + offset;
|
let mut write_offset = self.0.from + offset;
|
||||||
for chunk in data.chunks(block_size) {
|
for chunk in data.chunks(block_size) {
|
||||||
trace!("Wrote chunk at {}: {:?}", write_offset, chunk);
|
trace!("Wrote chunk at {}: {:?}", write_offset, chunk);
|
||||||
flash.write(write_offset as u32, chunk).await?;
|
flash.write(write_offset as u32, chunk).await?;
|
||||||
@ -838,7 +868,7 @@ impl<'a> FirmwareWriter<'a> {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Failing to meet alignment and size requirements may result in a panic.
|
/// Failing to meet alignment and size requirements may result in a panic.
|
||||||
pub fn write_firmware_blocking<F: NorFlash>(
|
pub fn write_block_blocking<F: NorFlash>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
@ -847,11 +877,11 @@ impl<'a> FirmwareWriter<'a> {
|
|||||||
) -> Result<(), F::Error> {
|
) -> Result<(), F::Error> {
|
||||||
trace!(
|
trace!(
|
||||||
"Writing firmware at offset 0x{:x} len {}",
|
"Writing firmware at offset 0x{:x} len {}",
|
||||||
self.0.dfu.from + offset,
|
self.0.from + offset,
|
||||||
data.len()
|
data.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut write_offset = self.0.dfu.from + offset;
|
let mut write_offset = self.0.from + offset;
|
||||||
for chunk in data.chunks(block_size) {
|
for chunk in data.chunks(block_size) {
|
||||||
trace!("Wrote chunk at {}: {:?}", write_offset, chunk);
|
trace!("Wrote chunk at {}: {:?}", write_offset, chunk);
|
||||||
flash.write(write_offset as u32, chunk)?;
|
flash.write(write_offset as u32, chunk)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user