9.4.3 Memory Management
Due to unpredictable and dynamic nature of network links in multi-hop wireless networks like ZigBee, the firmware image can only be transferred to the client using the best effort facilities for data transfer. At any given point in time the client which has downloaded only a part of the image may become disconnected from the network. Since in the general case it is impossible to avoid such a scenario, it helps to ensure that the entire image is received before any part of it irreversibly overwrites any part of the currently running image. This requires an architecture where whole and partially downloaded firmware images can be stored in a dedicated, nonvolatile firmware image store decoupled from the flash memory holding the currently executing application image.
PIC32CX-BZ3/WBZ35 family of devices has enough Embedded Flash memory to hold the new upgradable OTA image until new image is authenticated. The image is received in blocks over Zigbee link. If the image is encrypted, will be decrypted and stored in Embedded Flash Slot1. Once the complete image is received, image is validated for signature. Then the device reset will trigger the bootloader in Boot Flash region to load the image from Slot1 to Slot0. Now the new firmware starts executing.
Here is the memory split for PIC32CX-BZ3/WBZ35 embedded Flash for OTA DFU:
The above memory split is handled in linker script as shown below:
#ifndef PDS_LENGTH
#define PDS_LENGTH 0x4000
#endif
#define ROM_BASE_ADDR 0x01000000
#define METADATA_HEADER_SIZE 0x200
#define SLOT0_BASE_ADDR ROM_BASE_ADDR
#define SLOT1_BASE_ADDR 0x01080000
#ifndef ROM_ORIGIN1
#define ROM_ORIGIN1 SLOT0_BASE_ADDR + METADATA_HEADER_SIZE
#endif
#ifndef ROM_LENGTH1
#define ROM_LENGTH1 (SLOT1_BASE_ADDR - SLOT0_BASE_ADDR - PDS_LENGTH - METADATA_HEADER_SIZE)
#elif (ROM_LENGTH1 > 0x100000)
#error ROM_LENGTH1 is greater than the max size of 0x100000-0x200
#endif
#ifndef PDS_ORIGIN
#define PDS_ORIGIN (ROM_ORIGIN1 + ROM_LENGTH1)
#endif
#ifndef ROM_ORIGIN2
# define ROM_ORIGIN2 SLOT1_BASE_ADDR
#endif
#ifndef ROM_LENGTH2
#define ROM_LENGTH2 0x0080000
#elif (ROM_LENGTH2 > 0x100000)
#error ROM_LENGTH2 is greater than the max size of 0x100000
#endif
#ifndef BOOT_ROM_ORIGIN
# define BOOT_ROM_ORIGIN 0x0
#endif
#ifndef BOOT_ROM_LENGTH
# define BOOT_ROM_LENGTH 0x5e00
#elif (BOOT_ROM_LENGTH > 0x5e00)
# error BOOT_ROM_LENGTH is greater than the max size of 0x5e00
#endif