In this lesson, you will learn how to design a state machine to safely manage the transition between your application and the firmware update mode.
The Necessity of State Management
When performing an In-Application Programming (IAP) update, the device must shift from its primary task to an update mode where it can receive and write new code to flash. If a power failure or a command error occurs during this transition, the device could become "bricked." A robust state machine prevents this by ensuring that the system only enters the update mode when it is in a "known good" configuration.
Defining the Update State Machine
A simple state machine for this process uses discrete states to ensure data integrity. We typically define an enumeration to handle these transitions:
typedef enum {
SYSTEM_STATE_RUNNING, // Normal operation
SYSTEM_STATE_PREPARE_UPDATE,// Validating jump intent
SYSTEM_STATE_UPDATING, // Flash writing phase
SYSTEM_STATE_VERIFYING, // Post-update CRC check
SYSTEM_STATE_REBOOT // Resetting to new image
} system_state_t;
When your application receives a trigger (such as a specific command packet or a user-held pin), you do not jump directly to the bootloader. Instead, you transition the system into SYSTEM_STATE_PREPARE_UPDATE. In this state, you should:
- Disable all hardware interrupts to prevent unexpected ISR calls from interfering with memory writes.
- Flag the update intent in a non-volatile "Update Request" register (or a specific location in RAM that survives a soft reset).
- Verify system health (e.g., check that battery voltage is sufficient to complete the write).
Once these safety checks pass, the software triggers a system reset. During the startup sequence (which you learned about in previous lessons), the bootloader checks this "Update Request" flag. If set, it moves to SYSTEM_STATE_UPDATING. If the system resets unexpectedly without this flag, the bootloader knows to skip the update and return to the main application, keeping the device responsive. This separation of "intent" from "execution" is the cornerstone of a recoverable firmware update protocol.
Key Takeaway: By using a formal state machine to guard the transition into update mode, you ensure that the system only performs flash modifications when environmental conditions are verified, preventing bricked devices due to premature state changes.