1. Firmware update Over The Air profile
1.1. Overview
The Zigbee firmware update Over The Air (Zigbee OTA or FUOTA) service provides the possibility to receive a new application to be installed, while the current application is running. It requires to add the FUOTA service & characteristics to the current application.
The Zigbee FUOTA application allows to:
- Download the new Zigbee application in a free area – download slot,
- Jump to the Zigbee_ApplicationInstallManager.
The Zigbee_ApplicationInstallManager allows to:
- Perform the sanity checks of the downloaded image application.
- Replace the Zigbee application to be used after reboot.
| Memory mapping example for WBA55 - used on OTA application Zigbee_Thermostat_Server_Router_OTA |
|---|
| Memory mapping example for WBA65 |
|---|
There are three regions with programmable size and address which are not modified along the firmware update:
- One region that contains the Zigbee_ApplicationInstallManager.
- This region must be at the boot address of the CPU out of power on.
- The Zigbee_ApplicationInstallManager is a full binary with its own vector table.
- The active slot contains the application (user + FUOTA application) binary.
- The download slot is used only to store the application update to be applied.
The Keyword_User is used to ensure the firmware update has been fully received.
- The Keyword_User is placed at the end of the binary. It must be defined with a magic value (0xF11E0BEE) that cannot be found anywhere else in the firmware.
- A variable containing the address of the Keyword_User is placed just after the vector table, at a fixed address. This variable is initialized with the address of the Keyword_User. This address is defined at link time. The linker file can be used to ensure the Keyword_User is placed at the end of the binary.
This solution needs a post-script processing called ImageBuilderST.py to generate the image header in addition to the standard build process of the image.
This mechanism only ensures that the expected amount of bytes is written in the flash memory. It does not protect against data that may not be properly written in the flash memory.
Note that the OTA mechanism is not "plug and play" when adding the persistence mechanism since the persistence data might collide with the active slot or the download slot. On the address mapping above, the persistence data is written with "NVM". The download slot and the NVM slot have to be two dedicated slots.
1.2. Implementation with OTA cluster
The following table lists some examples of APIs used with OTA cluster - the list is not exhaustive.
| Function | Description |
|---|---|
| ZbZclOtaServerImageNotifyReq | Notify clients that an OTA image is available |
| ZbZclOtaClientAlloc | Create new OTA client cluster |
| ZbZclOtaClientDiscover | Discover OTA server |
| ZbZclOtaClientQueryNextImageReq | Request image info to server previous to transfer it |
| ZbZclOtaClientImageTransferStart | Initiate an OTA transfer |
| ZbZclOtaClientImageTransferResume | Resume an OTA upgrade transfer |
| ZbZclOtaServerUpgradeEndRespUnsolic | Start an OTA client update |
| AppZbOtaClient_DiscoverCompleteCallback | Callback discover completed received from server answering to client ZbZclOtaClientDiscover |
| AppZbOtaClient_ImageNotifyCallback | Callback client ImageNotify received from Server ZbZclOtaServerImageNotifyReq |
| AppZbOtaClient_QueryNextImageCallback | Callback query next image response received |
| AppZbOtaClient_UpgradeEndCallback | Callback client UpgradeEnd response received |
| AppZbOtaClient_RebootCallback | Callback reboot |
| AppZbOtaClient_AbortDownloadCallback | Callback abort in case of timeout or internal error |
| AppZbOtaServer_ImageEvalCallback | Server callback query next image request received from client |
| AppZbOtaServer_ImageReadCallback | Server callback image block request received from client |
| AppZbOtaServer_ImageUpgradeEndReqCallback | Server callback image upgrade end request received from client |
The Zigbee OTA flow between two devices using the OTA cluster and above API is the following:
| OTA Zigbee upgrade diagram |
|---|
Once the OTA transfer is complete, the Zigbee application install manager is performing step 3 deleting active slot, step 4 installing Firmware Update, and step 5 deleting download slot on the client side:
| Zigbee FUOTA steps |
|---|
After step 2 downloading the firmware update, an additional step can be performed to check the integrity of the image previous to move to step 3. Moving to step 3 is done by doing a system reset that restart the Zigbee_ApplicationInstallManager. Previous to step 3 deleting active slot, the Zigbee_ApplicationInstallManager verify the signature (and eventually a certificate key) before proceeding to the deleting. Previous to step 5 deleting download slot, the Zigbee_ApplicationInstallManager verify that the active slot is functional (some additional checks can be performed).
1.3. Implementation of Zigbee OTA client or server with CubeMX
The added feature of Zigbee OTA client (or server) can be easily added on any Zigbee profile, and on any Zigbee example with the highlighted CubeMX (latest version) fields:
| OTA Zigbee CubeMX settings, OTA client, OTA endpoint number, home automation OTA profile |
|---|
1.4. Notification and query image response data
Application starts OTA with the broadcast frame ZCL OTA: Image Notify and with the unicast frame ZCL OTA: Query Next Image Response.
Both frames contains Image data composed as follows:
| Zigbee OTA Image information data | |||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
2. Requirements
2.1. Software and hardware requirements
For the introduction of software and hardware requirements, refer to Bluetooth® LE STM32WBA Build BLE Project wiki page, and apply it to the Zigbee WBA55CG OTA application.
2.2. Zigbee_Thermostat_Server_Router_OTA readme
Since the readme of the Zigbee OTA applications have some differences versus the other Zigbee application, part of the Zigbee_Thermostat_Server_Router_OTA readme is provided.
How to use it? Open your preferred toolchain: Rebuild all files (Zigbee_ApplicationInstallManager, Zigbee_Thermostat_Server_Router_OTA and Zigbee_Thermostat_Client_Coord_OTA). On the directory of your preferred toolchain launch 'ImageBuilderST.bat' that create the image of file: ZigbeeThermostatServerRouterOTA_Image.bin. Flash the first board (Device): Zigbee_ApplicationInstallManager binary file is downloaded at the memory address 0x08000000 Zigbee_Thermostat_Server_Router_OTA binary file is downloaded at the memory address 0x08006000 Flash the second board (Coordinator): Zigbee_Thermostat_Client_Coord_OTA binary file is downloaded at the memory address 0x08000000 ZigbeeThermostatServerRouterOTA_Image.bin binary file is downloaded at the memory address 0x08080000
2.3. Zigbee_Thermostat_Server_Router_OTA STM32CubeProgrammer
Flashing at the address 0x08006000 with STM32CubeProgrammer the Projects\NUCLEO-WBA55CG\Applications\Zigbee\Zigbee_Thermostat_Server_Router_OTA\EWARM\ZB_Therm_SrvRt_OTA\Exe\Zigbee_Thermostat_Server_Router_OTA.bin EWARM binary (Keil or CubeIDE are also available) is displayed as an example here:
| OTA Zigbee STM32CubeProgrammer: flash project Zigbee_Thermostat_Server_Router_OTA.bin |
|---|
Run after programming should be untick in this case.
2.4. Zigbee_Thermostat_Server_Router_OTA_Image ImageBuilderST.py
Creating the image of file ZigbeeThermostatServerRouterOTA_Image.bin with EWARM/ImageBuilderST.bat:
py.exe ../../Zigbee_ApplicationInstallManager/ImageBuilder/ImageBuilderST.py \ --create ZB_Therm_SrvRt_OTA/Exe/Zigbee_Thermostat_Server_Router_OTA.bin \ --output ZB_Therm_SrvRt_OTA/Exe/ZigbeeThermostatServerRouterOTA_Image.bin \ --manuf-id 0x1041 --image-type 0x01 --version 0x2000 \ --header-string "Thermostat Server Router OTA"
It performs the addition of the manufacturer id 0x1041, the image_type and the version as an header on the output bin ZigbeeThermostatServerRouterOTA_Image.bin. In wireshark, at the begining of a Zigbee OTA, the frame ZCL OTA: Image Notify and the frame ZCL OTA: Query Next Image Response contains the manufacturer code, the image_type and the above version.
3. STM32WBA Zigbee FUOTA example description
The Zigbee FUOTA service embedded in Zigbee_Thermostat_Client_Coord_OTA and Zigbee_Thermostat_Server_Router_OTA applications, as well as the Zigbee_ApplicationInstallManager, are available by downloading STM32CubeWBA MCU Package[1], and are available on the WBA55 nucleo directory.
3.1. Project Zigbee_ApplicationInstallManager
Software project structure with the most important parts:
| Zigbee_ApplicationInstallManager structure |
|---|
Once the firmware update is fully received, the Zigbee_ApplicationInstallManager installs it from the download slot to the active slot.
When there is no firmware update to be installed, it jumps on the reset vector of the application. It cannot be updated with FUOTA.
3.2. Project example OTA client
| Zigbee_Thermostat_Server_Router_OTA project structure |
|---|
This is a single binary implementing both the Thermostat_Server and the OTA client application.
The Zigbee_Thermostat_Server_Router_OTA application is responsible for downloading the firmware update in the download slot and in parallel is doing the thermostat periodic transmit to the coordinator.
This binary (including both the User and the OTA application) can be updated with FUOTA.
3.3. Project example OTA server
| Zigbee_Thermostat_Client_Coord_OTA project structure |
|---|
4. Zigbee OTA Flow
| FUOTA flow diagram between Zigbee_ApplicationInstallManager and Zigbee_Thermostat_Server_Router_OTA user application |
|---|
| FUOTA Steps |
|---|
In parallel, both the user application thermostat service and the Zigbee FUOTA service are running.
It is possible to download a new firmware update while the user application keeps running.
Once the firmware download is completed, the application reboots the device to install it.
When Standby mode is set in the user application with FUOTA, to preserve RAM integrity of the user FUOTA Application, after each wake-up reset from the Standby mode, the user FUOTA Application must be run immediately with a minimum RAM use (skip of Zigbee_ApplicationInstallManager tasks).
4.1. Application customer specific modifications: Download start address
In the application example Zigbee_Thermostat_Client_Coord_OTA\STM32_WPAN\App\app_zigbee_ota_defines.h and Zigbee_Thermostat_Server_Router_OTA\STM32_WPAN\App\app_zigbee_ota_defines.h:
#define FUOTA_FW_APP_MANUFACTURER_CODE 0x1041u /* ST Tests */ ##define FUOTA_FW_APP_IMAGE_TYPE (uint16_t)0x01u /* FW Application Image Type. */ # #/* Flash Memory defines */ ##define FUOTA_APP_DOWNLOAD_BINARY_BANK FLASH_BANK_1 /* Application Download Binary in the First Back */ ##define FUOTA_APP_DOWNLOAD_BINARY_ADDRESS 0x08080000 /* Application Download Binary Address. For STM32WBA5x. */
The address FUOTA_APP_DOWNLOAD_BINARY_ADDRESS can be changed to adapt to WBA6 or other customer requirements.
In the scatter EWARM file of the application example Zigbee_Thermostat_Server_Router_OTA\EWARM\stm32wba55xx_flash_ota.icf:
/*-Memory Regions-*/ define symbol __ICFEDIT_region_DOWNLOAD_end__ = 0x080FFFFF; define symbol __ICFEDIT_region_DOWNLOAD_start__ = 0x08080000;
The same address 0x08080000 (__ICFEDIT_region_DOWNLOAD_start__) can be changed to adapt to WBA6 or other customer requirements.
4.2. Slowing down the OTA with image_block_delay
If an OTA resume methodology is assessed for any reason, a method to increase the robustness of the OTA transfer is to increase the delay between image block requests (from block n to block n+1) using the parameter image_block_delay on the client side. The default value for image_block_delay is 50ms. Increasing the image_block_delay to 100ms will slow down the OTA transfer by a factor of two. Slowing down the OTA might be necessary in noisy environments or when the image needs to be transmitted through multiple routers (multiple hops).
STM32WBA code to modify the value of image_block_delay:
stOtaClientConfig.endpoint = stCurrentOtaClientInfo.cEndpoint; stOtaClientConfig.profile_id = stCurrentOtaClientInfo.iProfile; stOtaClientConfig..image_block_delay = 250u; stOtaClientConfig.activation_policy = stCurrentOtaClientInfo.eActivationPolicy; stOtaClientConfig.timeout_policy = stCurrentOtaClientInfo.eTimeOutPolicy;
5. Details on Zigbee block OTA data size
The data size for an OTA has a minor impact on the duration of the OTA image transfer. This chapter details the headers that directly impact the number of bytes available for the OTA data size. Some network parameters also affect the OTA data size, which has been arbitrarily chosen to be 49 bytes. This conservative choice allows for a wide range of network topologies and all possible security levels and can be considered a stack requirement.
In the context of Zigbee, the Maximum Transmission Unit (MTU) size refers to the maximum size of a data packet that can be transmitted over the network, including both the header and the payload. The Zigbee protocol typically supports a maximum MTU size of 127 bytes at the physical layer. These 0-127 bytes are also called PSDU for PHY Service Data Unit and are referred to as IEEE 802.15.4 data in Wireshark.
In the context of Zigbee OTA, the "ZCL OTA: image block request" frames and "ZCL OTA: image block response" frames are ZCL frames. These frames are used within the Zigbee protocol to facilitate communication between devices using the Zigbee Cluster Library. These frames typically contain:
- MAC Header: Includes frame control, sequence number, addresses, etc.
- NWK Header: Includes network-specific information like source and destination addresses, radius, etc.
- APS Header: Application support sub-layer information.
- ZCL Header: Zigbee Cluster Library-specific information.
- Payload: The actual data being transmitted.
- Security Overhead: If security is enabled, additional bytes are used for the auxiliary security header and Message Integrity Code (MIC).
5.1. Zigbee ZCL OTA:image block request Frame typical exemple for STM32WBA Structure
5.1.1. 1. MAC layer
- Frame control: 2 bytes
- Sequence number: 1 byte
- Destination PAN ID: 2 bytes
- Destination address: 2 bytes (short address) or 8 bytes (extended address)
- Source address: 2 bytes (short address) or 8 bytes (extended address)
5.1.2. 2. NWK layer
- Frame control: 2 bytes
- Destination address: 2 bytes
- Source address: 2 bytes
- Radius: 1 byte
- Sequence number: 1 byte
5.1.2.1. Optional NWK security
- Auxiliary security header: 5 to 14 bytes (depending on security level)
- Security control: 1 byte
- Frame counter: 4 bytes
- Extended source address: 0 or 8 bytes (optional)
- Key sequence number: 0 or 1 byte (optional, positioned after Extended Source Address)
- Message integrity code (MIC): 4 bytes
5.1.3. 3. APS layer
- Frame control: 1 byte
- Destination endpoint: 1 byte
- Cluster ID: 2 bytes (0x0019 for OTA)
- Profile ID: 2 bytes (0x0104 for Zigbee HA)
- Source endpoint: 1 byte
- APS counter: 1 byte
5.1.4. 4. ZCL layer
- Frame control: 1 byte
- Transaction sequence number: 1 byte
- Command ID: 1 byte (0x05 for image block response)
Payload
- Status: 1 byte
- Manufacturer code: 2 bytes
- Image type: 2 bytes
- File version: 4 bytes
- File offset: 4 bytes
- Data size: 1 byte (set to 49)
- Image data: 49 bytes
5.2. Example byte-by-byte breakdown
<MAC Layer: Byte 0-1: Frame Control Byte 2: Sequence Number Byte 3-4: Destination PAN ID Byte 5-6: Destination Address Byte 7-8: Source Address NWK Layer: Byte 9-10: NWK Frame Control (2 bytes) Byte 11-12: Destination Address Byte 13-14: Source Address Byte 15: Radius Byte 16: NWK Sequence Number Optional NWK Security: Byte 17: Security Control Byte 18-21: Frame Counter Byte 22-29: Extended Source Address (if used) Byte 30: Key Sequence Number (if used) Byte 31-34: MIC (4 bytes) APS Layer: Byte 35: APS Frame Control Byte 36: Destination Endpoint Byte 37-38: Cluster ID (0x0019 for OTA) Byte 39-40: Profile ID (0x0104 for Zigbee HA) Byte 41: Source Endpoint Byte 42: APS Counter ZCL Layer: Byte 43: ZCL Frame Control Byte 44: Transaction Sequence Number Byte 45: Command ID (0x05 for image block response) Payload: Byte 46: Status Byte 47-48: Manufacturer Code Byte 49-50: Image Type Byte 51-54: File Version Byte 55-58: File Offset Byte 59: Data Size (set to 49) Byte 60-108: Image Data (49 bytes)
To link it with some Zigbee STM32WBA (or STM32WB) stack parameters:
Network Layer (NWK) Security: When NWK security is enabled, an auxiliary security header and a Message Integrity Code (MIC) are added to the NWK frame. The size of these security components depends on the chosen security level.
#define ZB_NWK_CONST_MIN_HEADER_OVERHEAD 0x08U
#define ZB_NWK_CONST_SECURITY_LEVEL 0x05U
#define ZB_SEC_MIC_LENGTH_5 4U
#define ZB_NWK_CONST_SECURITY_OVERHEAD (14U + 4U=18U)
Those 18 Bytes of ZB_NWK_CONST_SECURITY_OVERHEAD are taken into account in the previous chapter Example Byte-by-Byte Breakdown.
Source Routing Overhead: Many-to-one source routing adds overhead to the NWK header. Each hop in the source route requires additional bytes. With a source routing level of 6, the NWK header needs to accommodate the addresses of six intermediate nodes.
/* Source Routing Overhead */ 4U
/* source router header */ 2U * ZB_NWK_CONST_DEFAULT_SOURCE_ROUTE
#define ZB_NWK_CONST_DEFAULT_SOURCE_ROUTE 6U
Those 4+2*6=16 bytes of source routing overhead are not taken into account in the previous chapter Example Byte-by-Byte Breakdown.
6. References
