1.9.1 How the OTA Bootloader Library Works
OTA Bootloader - Dual Bank (For MCUs)
This is a OTA bootloader which resides from:
The starting location of the Flash memory region for SAM devices
The starting location of the Boot Flash memory region for PIC32M devices
- Uses a Custom linker script btl.ld to place it in Boot Flash memory
Performs Below Operation:
Read the control block stored in the last sector of dual bank memory
Checks if blockUpdated field is set to 1, then it will update the control block
- SAM devices: If blockUpdated field is set to 0 then it jumps to application space to run the OTA application
- PIC32M devices: If blockUpdated field is set to 0 then map Program Flash Bank with higher serial number to the lower region and then it jumps to Step 4
Set blockUpdated field to 0 and then update the control block in the dual bank Flash memory. And perform the following operation.
- SAM devices: Swap bank and trigger reset
- PIC32M devices: Trigger reset
Run OTA application as below:
Calls the SYS_Deinitialize() function which releases the resources used. This Function is device specific and has to be implemented based on application requirement.
Jumps to application space to run the OTA application

OTA Bootloader - External Memory (For MCUs)
This is a OTA bootloader which resides from:
The starting location of the Flash memory region for SAM devices
The starting location of the Boot Flash memory region for PIC32M devices
- Uses a Custom linker script btl.ld to place it in Boot Flash memory
Performs Below Operation:
Read the control block stored in the last sector of external memory
Checks if blockUpdated field is set to 1, then it will update the application binary
- If blockUpdated field is set to 0 then it jumps to application space to run the OTA application
If application update is required then it
- Reads the OTA application binary stored from loadAddress in the external memory
- Programs the read binary to programAddress in the Internal Flash
Once programming is done it generates a CRC32 value over programmed space and verifies it against the CRC32 stored in external memory control block
If verification is successful then set blockUpdated field to 0 and then update the control block in the external memory and trigger reset
Run OTA application as below:
Calls the SYS_Deinitialize() function which releases the resources used. This Function is device specific and has to be implemented based on application requirement.
Jumps to application space to run the OTA application

Note: At first bootup, the application to be bootloaded has to be programmed along with bootloader using the external programmer or debugger.
MPU OTA Bootloader and Applications Block Diagram

OTA Bootloader
This is a bootloader application which resides from:
OTA Bootloader stored into SD/NAND/Serial Flash memory
OTA Bootloader executes from DDR memory. AT91Bootstrap loads OTA bootloader from SD/NAND/Serial Flash memory to DDR memory and executes it.
Then OTA Bootloader loads OTA application image from SD/NAND/Serial Flash memory to DDR memory and executes it
Performs Below Operation:
Read the metadata (image size) stored in the external memory
Reads the OTA application binary stored from the external memory and Programs the binary to the DDR memory
Run OTA application as below
Calls the SYS_Deinitialize() function which releases the resources used. This Function is device specific and has to be implemented based on application requirement.
Jumps to application space to run the OTA application
OTA Application
This is a OTA application which resides from:
- OTA Application stored into SD/NAND/Serial Flash memory
It blinks an LED and provides console output
It calls the OTA_SERVICE_Tasks() function which receives the binary over OTA to be programmed into the external memory
Once the binary is received and programmed into the external memory, it generates a CRC32 value over programmed external memory space and verifies it against the received CRC32
If verification is successful then it updates the metadata (image size) and trigger reset to run new application binary through OTA bootloader
Bootloader Control Block (Metadata)
/* Per app image info to store in this structure for bootloader/OTA service * Note: The order of the members should not be changed */ typedef struct __attribute__((packed)) { unsigned int status : 3; unsigned int signaturePresent : 1; unsigned int filenamePresent : 1; unsigned int imageEncrypted : 1; unsigned int reserved : 2; unsigned int imageType : 4; unsigned int imageStorage : 4; unsigned int versionNum : 4; unsigned int format : 4; unsigned int signatureType : 8; uint32_t programAddress; uint32_t jumpAddress; uint32_t loadAddress; uint8_t signature[8]; uint32_t imageSize; } APP_IMAGE_INFO;
Dual Bank (for Cortex-M based MCU)
/* Control block (Metadata) structure for bootloader/OTA service
* Note: The order of the members should not be changed
*/
typedef struct
{
unsigned int versionNum : 4;
unsigned int ActiveImageNum : 4;
unsigned int blockUpdated : 1;
unsigned int reserved : 23;
APP_IMAGE_INFO appImageInfo[1];
} OTA_CONTROL_BLOCK;Dual Bank (for MIPS based MCU)
/* Control block (Metadata) structure for bootloader/OTA service
* Note: The order of the members should not be changed
*/
typedef struct
{
uint32_t serialNum;
unsigned int versionNum : 4;
unsigned int ActiveImageNum : 4;
unsigned int blockUpdated : 1;
unsigned int reserved : 23;
APP_IMAGE_INFO appImageInfo[1];
} OTA_CONTROL_BLOCK;External Memory
/* Control block (Metadata) structure for bootloader/OTA service
* Note: The order of the members should not be changed
*/
typedef struct
{
unsigned int versionNum : 4;
unsigned int ActiveImageNum : 4;
unsigned int blockUpdated : 1;
unsigned int reserved : 23;
APP_IMAGE_INFO appImageInfo[2];
} OTA_CONTROL_BLOCK;Note: For External Memory (For MCUs), Per app image info can be configured through MCC (e.g., APP_IMAGE_INFO appImageInfo;, where x is number of app image).
- For MCUs: The above Control Block (Metadata) for application has to be stored in last page of inactive bank (or external memory) required by bootloader
- For MPUs: Per app image info is fixed with 1 value (e.g., APP_IMAGE_INFO appImageInfo;)
