Integrating the Device Management Update client into your user application
This tutorial explains how to build a firmware update that includes the Device Management Update client. Integrating this client into the firmware update enables you to update devices that are connected to Device Management.
This tutorial shows you how to:
- Configure the user application to use the Device Management Update client.
- Authorize the user application to install the firmware update.
- Use callbacks to monitor the download progress of the firmware update.
- Handle errors from the Device Management Update client.
Configure the user application to use the Device Management Update client
To update the firmware on a device connected to Device Management, you need to configure the application to use the Update client. Add the following code to this configuration file mbed_cloud_client_user_config.h
:
#define MBED_CLOUD_CLIENT_SUPPORT_UPDATE
#define MBED_CLOUD_CLIENT_UPDATE_ID
#define MBED_CLOUD_CLIENT_UPDATE_CERT
#define MBED_CLOUD_CLIENT_UPDATE_BUFFER 2048
Note: The buffer value can vary depending on your specific board.
Authorize the application to install the firmware update
The Update client is transparent to the user application, apart from these optional callbacks:
- The authorization function.
- The download progress callback.
- The error handler.
Authorization function
During a firmware update, the Update client might ask the user application's permission to download the new update candidate image and then install it and reboot the device. Because the firmware update process is resource-intensive, you can use the authorization function to let the application schedule the update for an off-peak period.
If you do not include the authorization function, the Update client assumes it can start the updating the firmware immediately.
In the following code example, the update_authorize
function is called whenever Update client wants to download, or reboot and install. The user application must call MbedCloudClient::update_authorize(REQESTED_ACTION)
to authorize the Device Management Update client to proceed with the requested action.
/* 'mbed_cloud_client' is of type (MbedCloudClient*) below. */
void update_authorize(arm_uc_request_t request)
{
switch (request)
{
/* Cloud Client wishes to download new firmware. This can have a negative
impact on the performance of the rest of the system.
The user application is supposed to pause performance sensitive tasks
before authorizing the download.
Note: the authorization call can be postponed and called later.
This doesn't affect the performance of the Cloud Client.
*/
case MbedCloudClient::UpdateRequestDownload:
printf("Firmware download requested\r\n");
printf("Authorization granted\r\n");
mbed_cloud_client->update_authorize(MbedCloudClient::UpdateRequestDownload)
break;
/* Cloud Client wishes to reboot and apply the new firmware.
The user application is supposed to save all current work before rebooting.
Note: the authorization call can be postponed and called later.
This doesn't affect the performance of the Cloud Client.
*/
case MbedCloudClient::UpdateRequestInstall:
printf("Firmware install requested\r\n");
printf("Authorization granted\r\n");
mbed_cloud_client->update_authorize(MbedCloudClient::UpdateRequestInstall);
break;
default:
printf("Error - unknown request\r\n");
break;
}
}
mbed_cloud_client->set_update_authorize_handler(update_authorize);
Download progress
You can use the download progress function to register a callback to monitor the progress of the firmware download. Each time the Update client downloads a firmware chunk, the Update client calls the callback function with two parameters:
total
: the firmware's total size (in bytes).progress
: the downloaded size (in bytes).
/**
* \brief Registers a callback function for monitoring download progress.
* \param handler Callback function.
*/
void set_update_progress_handler(void (*handler)(uint32_t progress, uint32_t total));
Example usage
/* 'mbed_cloud_client' is of type (MbedCloudClient*) below. */
void update_progress(uint32_t progress, uint32_t total)
{
uint8_t percent = progress * 100 / total;
printf("Downloading: %d %%\r\n", percent);
if (progress == total)
{
printf("\r\nDownload completed\r\n");
}
}
mbed_cloud_client->set_update_progress_handler(update_progress);
Errors
The Update client reports errors through the error handler MbedCloudClient::on_error(&error);
. Your user application needs to know how to handle each of these errors appropriately. Error codes fall into three categories of severity:
- Warning: An error occurred, but the user application needs no action on the device. However, an action might be necessary in the cloud. For example, an invalid manifest would require an action in the cloud but not on the device.
- Error: An error occurred that requires action by the user application. For example, if a new firmware image exceeds the available space, the user application could free up space.
- Fatal: An unrecoverable error occurred, and the user application should reboot when it is safe to do so.
For more detail, refer to the list of error codes.
Next step: Build the firmware update
Next, you need to compile the firmware image and load it on to your device. The steps you follow depend upon the device platform; if you are using:
- an Mbed OS device, follow the instructions for building a firmware update for an Mbed OS device.
- Raspberry Pi 3, follow the instructions for building a firmware image for the Raspberry Pi 3.