Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ The `ec-slimloader` crate will handle for you:
* it will read from the state journal what image slot will be booted.
* on subsequent reboots, it will fall back to your defined backup slot if you do not mark your current application image as `confirmed`.

If that backup fails validation and differs from the target, the loader also tries the target before giving up. It records `Attempting` before this reverse fallback, so the application identifies the correct running slot and inactive update slot. Each distinct candidate is checked at most once per boot.

However, some aspects are handled by the platform support crate (and can differ from project-to-project):
* how application images are loaded. For `ec-slimloader-imxrt` images are copied to RAM in a quite chip-specific way. Typically for other platforms you might want to swap images between on-chip NOR flash and external NOR flash. The latter method is not implemented in this repository (yet).
* how application images are verified. By default the images themselves are not checked at all. `ec-slimloader-imxrt` leverages the native NXP authentication routines to check image integrity.
Expand Down
10 changes: 10 additions & 0 deletions libs/ec-slimloader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ pub async fn start<B: Board, const JOURNAL_BUFFER_SIZE: usize>(config: B::Config
info!("Attempting to boot backup in {:?}", slot);
let error = board.check_and_boot(&state.backup()).await; // If this function returns, it implies that the boot has failed.
warn!("Failed to boot backup in {:?} because {:?}", slot, error);
} else if slot != state.target() {
Comment thread
JamesHuard marked this conversation as resolved.
Resolved
// We started in [Attempting] or [Failed], so the backup was tried first and could not boot.
// The target has not been tried this boot; an interrupted earlier attempt may have left it usable.
// Try the target as a last resort, recording [Attempting] in the journal so the app
// identifies the target as running and writes future updates to the backup.

set_status::<_, JOURNAL_BUFFER_SIZE>(&mut board, &mut state, Status::Attempting).await;
Comment thread
JamesHuard marked this conversation as resolved.
Resolved
info!("Backup unusable, retrying target {:?}", state.target());
let error = board.check_and_boot(&state.target()).await;
Comment thread
gjpmsft marked this conversation as resolved.
Resolved
warn!("Failed to boot target {:?} because {:?}", state.target(), error);
}

error!("No candidates booted successfully, giving up...");
Expand Down
Loading