1.10.2 Firmware Upgrade Flow

On every start-up, the bootloader reads a boot-mode record stored in the BOOT_FLAG sector of the external serial Flash and acts accordingly:

Table 1-8. Boot Modes
Boot ModeAction
NORMALJump to the application
INSTALL_PENDINGInstall the image bundle staged in the DOWNLOAD zone, clear the record to NORMAL and start the application
REVERT_PENDINGRestore the previous images from the REVERT zones, clear the record to NORMAL and start the application
UART_PENDINGEnter the Serial Recovery mode and wait for the host, even if no install or revert is pending (see UART Recovery Mode)

The DOWNLOAD zone is the single staging area for a firmware upgrade. It is written either by the application during a PRIME firmware upgrade over PLC — which validates the bundle (CRC and signature), writes the INSTALL_PENDING record and resets — or by the PRIME_H3_SAMD20_Memory_Tool over the serial interface (see UART Recovery Mode). In both cases, the bootloader installs the bundle from the same DOWNLOAD zone, so the install path is identical.

To install, the bootloader processes each image. It first backs up the current copy (CURRENT → REVERT) and then writes the new payload — the application to the internal Flash and its mirror in APP_CURRENT, and the PL360 binary to PL360_CURRENT. A revert performs the opposite operation, restoring the REVERT copies. Each per-image step (backup and write) is persisted in the boot-mode record, so an interrupted install or revert resumes correctly after a power cut.

The bootloader trusts the validation already performed by the application (CRC and signature) and only verifies the structure of the bundle (magic words and sizes). It does not recompute the CRC or verify the signature.

Bundle Structure

The bundle is a single block with a structural header followed by the image payloads. All header fields are 32-bit values to maintain alignment on the Arm Cortex-M0+. A bundle can carry up to four images — typically the application and the PL360 binary, with two slots reserved for future use.

#define MAX_IMAGES_PER_BUNDLE   4

typedef struct __attribute__((packed)) {
    uint32_t typeMagic;            /* image type: 'APPC' or 'PLCC' */
    uint32_t offset;               /* offset from the start of the bundle to the payload */
    uint32_t size;                 /* payload size in bytes */
} BUNDLE_IMAGE;

typedef struct __attribute__((packed)) {
    uint32_t magicStart;           /* 'BNDL' */
    uint32_t bundleFormatVersion;  /* format version (1) */
    uint32_t totalSize;            /* bytes from magicStart up to (not including) magicEnd */
    uint32_t numImages;            /* number of images: 1 .. MAX_IMAGES_PER_BUNDLE */
    BUNDLE_IMAGE images[];         /* one descriptor per image */
    /* image payloads, concatenated at their offsets                */
    /* uint32_t magicEnd ('EBND') placed right after the last payload */
} BUNDLE_HEADER;

The header is followed by one descriptor per image, then the concatenated payloads, and finally the end magic word. The magic words identify the bundle and the type of each image:

Table 1-9. Bundle Magic Words
FieldValueMeaning
magicStart'BNDL'Marks the start of the bundle
magicEnd'EBND'Marks the end of the bundle, right after the last payload (used to detect an incomplete download)
typeMagic'APPC'The image is the application
typeMagic'PLCC'The image is the PL360 binary

Each image descriptor (BUNDLE_IMAGE) stores the type and the location of its payload within the bundle:

Table 1-10. Image Descriptor Fields
FieldDescription
typeMagicImage type: 'APPC' (application) or 'PLCC' (PL360 binary)
offsetOffset in bytes from the start of the bundle to the image payload
sizeImage payload size in bytes