Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 477 of 9366. Embedded Software Construction and ToolchainsFree lesson

Performing Atomic Firmware Swap Operations

Learners will implement a dual-bank flash update mechanism to ensure the system remains bootable if a power failure occurs during flashing.

In this lesson, you will learn how to transition a new firmware image into the active execution slot using a "bank-swap" mechanism that guarantees system recovery if power is lost mid-update.

The Problem of Partial Updates

If you overwrite your currently running firmware directly, a power failure during the write process leaves you with a "bricked" device—an image that is neither the old version nor the new one. To prevent this, we use two flash slots: Bank A (Active) and Bank B (Candidate).

The Atomic Swap Strategy

The key to atomicity is the Swap Flag located in a dedicated, non-volatile configuration sector. Instead of physically moving bits between memory regions, we treat the flash as two independent slots and use the metadata header to define which one the bootloader should execute.

  1. Download: Write the new firmware to the inactive slot (e.g., Bank B).
  2. Verify: Perform a CRC check on Bank B to ensure it is intact.
  3. Atomic Commit: Write a "Commit" flag to the header of Bank B.
  4. Reset: Trigger a system reset.

During the next boot, the bootloader checks the headers. It only attempts to jump to the address of the bank marked as "Valid" and "Committed." If power fails while writing the new firmware to Bank B, the "Commit" flag is never set, and the bootloader simply boots the old, safe image in Bank A.

Implementation Concept

The atomic transition happens in a single write operation to the header:

// Pseudo-code for committing the new firmware
void commit_firmware_update() {
    firmware_header_t header;
    header.status = STATUS_COMMITTED;
    header.crc = calculate_crc(BANK_B_START, BANK_B_SIZE);
    
    // The final, atomic write to the metadata flash sector
    flash_write(HEADER_BANK_B_ADDR, (uint8_t*)&header, sizeof(header));
    
    // Reboot to switch execution context
    system_reset();
}

By ensuring that the "Commit" flag is the last byte written, you guarantee that even if the system loses power a millisecond before the update is finished, the device remains in a stable, bootable state.

Key Takeaway: Atomicity in firmware updates is achieved not by moving data, but by using a non-volatile metadata flag that marks the new image as valid only after it has been fully verified.