Over The Air (OTA) Bootloader Abstraction Library
 All Data Structures Functions Variables Enumerations Enumerator Groups Pages
Over The Air(OTA) Bootloader Abstraction Library Overview

This library offers assistance for handling downloaded over-the-air (OTA) updates of the application code that is executed on a PSoCâ„¢ 6 Connectivity Device, a 20829(CYW920829M2EVK-02) Device, a 89829(CYW989829M2EVB-01) Device, or an XMC7200(KIT_XMC72_EVK) Device based on selected bootloader.

The library implements storage interface APIs required by ota-update library to complete OTA on supported platforms. Current version(v1.X) of ota-bootloader-abstraction has storage interface APIs for MCUBootloader based OTA.

The ModusToolbox MCUBootloader based OTA code examples import this library automatically along with ota-update library.

Features and Functionality

This library has implementation of storage interface APIs required by ota-update library to complete OTA on supported platforms.

Other features:

  • Template flashmaps for supported platforms.
  • Template OTA linker files for supported platforms and toolchains.
  • Prebuild and Postbuild scripts for generating BOOT and UPGRADE images of OTA Application.
  • OTA image signing scripts.

Integration Notes

To add different bootloader support on Infineon connectivity-enabled MCU platforms, ota-update library offloads bootloader dependent storage interface APIs using callback mechanism. To handle downloaded OTA upgrade images ota-update library calls registered storage interface callbacks. This ota-bootloader-abstraction library provides implementation of these storage interface APIs for different bootloaders along with build environment required to generate BOOT and UPGRADE images of OTA applications.
Current version of library supports only MCUBootloader based OTA image handling.

The user is expected to:

  1. Build and program MCUBootApp on the chosen platform(s) before enabling MCUBootloader based OTA in an application. Refer to refer to MCUBootApp README <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/MCUBOOT_APP_README.md.
  2. Update OTA Application Makefile by referring OTA Bootloader Abstraction Makefile Readme <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md.
  3. ota-bootloader-abstraction library has makefile mcuboot_support.mk located in <mtb_shared>/ota-bootloader-abstraction/<version>/makefiles/mcuboot/ which has necessary pre and post build scripts for generating MCUBootloader based BOOT and UPGRADE images of OTA application.
  4. Include mcuboot_support.mk which is located in <mtb_shared>/ota-bootloader-abstraction/<version>/makefiles/mcuboot/ from OTA Application Makefile.
  5. Configure OTA storage interface callback APIs in OTA application, And pass the same storage interface while starting OTA agent.
  6. OTA storage interface calls Flash operations(Read, Write, erase) to store upgrade images in UPGRADE slot. ota-bootloader-abstraction implements flash operation using mtb-pdl-cat1 library APIs and implementation is available in configs folder <mtb_shared>/ota-bootloader-abstraction/<version>/configs/COMPONENT_MCUBOOT/flash/. User can use same implementation by copying contents of <mtb_shared>/ota-bootloader-abstraction/<version>/configs/COMPONENT_MCUBOOT/flash/) to application space or Can implement flash operation APIs defined in <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/cy_ota_flash.h.
  7. For MCUBootloader based OTA Support, add the following to the project Makefile:
    CY_BOOTLOADER=MCUBOOT

  8. Add Application Build Directory in the project Makefile:
    CY_BUILD_LOCATION=<Application's Build Working Directory path>

  9. Add OTA platform in the project Makefile:
    OTA_PLATFORM=<platform_type>
    Refer OTA Bootloader Abstraction Makefile Readme <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/MCUBOOT_OTA_MAKEFILE_INFO_README.md.

  10. Add linker file path for MCUBootloader based OTA on choosen platform in the project Makefile:
    OTA_LINKER_FILE=<OTA linker file path>

    There are other components that may be needed based on support. Please refer to the various readme files in the folder <mtb_shared>/ota-bootloader-abstraction/<version>/source/COMPONENT_MCUBOOT/.
    MCUBOOT_APP_README.md
    MCUBOOT_BUILD_COMMANDS.md
    MCUBOOT_OTA_FLASH_LAYOUT_README.md
    MCUBOOT_OTA_MAKEFILE_INFO_README.md
    README.md in library root directory.

General Concept

The OTA Bootloader Abstraction provides bootloader specific storage interface API implementation which can be used with ota-update library for handling downloaded OTA application upgrade images. During reboot bootloader validates and boots upgrade image.

The basic device boot sequence is as follows:

  1. ROM boot will start Bootloader.
  2. Bootloader runs the current application(BOOT Image) in the Primary slot.
  3. The OTA Agent downloads the update(UPGRADE Image) and stores it in the Secondary slot using storage interface APIs.
  4. The OTA Agent marks the upgrade as ready using storage interface API.

    On the next system boot:
  1. ROM boot will start Bootloader.
  2. If no update is downloaded, Bootloader starts the current application.
  3. Bootloader determines if there is an update in the Secondary Slot.
  4. If there is an update available:
    a. Bootloader verifies the update.
    b. Bootloader boots upgrade image either by copying or switching Primary and Secondary Slots.
    c. The updated application must call cy_ota_storage_validated() to validate the update.

    MCUBootloader Support:
    This library has below support for MCUBootloader based OTA on PSoC6, 20829, 89829 and XMC7200 platforms.
  1. Template flashmaps for PSoC6, 20829, 89829 and XMC7200 platforms.
  2. Template linker files for GCC_ARM, ARM, and IAR toolchains.
  3. Storage operation callback APIs to handle MCUBootloader based upgrade image.
  4. Prebuild and Postbuild scripts for generating and signing MCUBootloader based BOOT and UPGRADE image of an OTA Application.

API Overview

1. Initialize Storage Area

cy_ota_storage_init() - Initializes flash, QSPI flash, or any other external memory type.
Application is expected to call this API once before starting OTA agent.
cy_rslt_t cy_ota_storage_init(void);

2. Open Storage Area

cy_ota_storage_open() - Open storage Area for storing OTA UPGRADE images.
Typically, this erases UPGRADE slots as well. The OTA agent will call this API once OTA image download starts.
cy_rslt_t cy_ota_storage_open(cy_ota_storage_context_t *storage_ptr);

3. Read data from Storage Area.

cy_ota_storage_read() - Read data from Storage Area.
The Read API is primarily used by OTA agents to read OTA Image headers.
cy_rslt_t cy_ota_storage_read(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_read_info_t *chunk_info);

4. Write data to Storage Area.

cy_ota_storage_write() - Write data to Storage Area.
The Write API is mainly utilized by OTA agents to write OTA upgrade images that have been downloaded.
cy_rslt_t cy_ota_storage_write(cy_ota_storage_context_t *storage_ptr, cy_ota_storage_write_info_t *chunk_info);

5. Close Storage Area.

cy_ota_storage_close() - Close Storage Area.
This API is responsible for closing the storage context. After the context is closed, it will not be possible to perform any write or read operations.
cy_rslt_t cy_ota_storage_close(cy_ota_storage_context_t *storage_ptr);

6. Verify downloaded UPGRADE OTA image.

cy_ota_storage_verify() - Verify OTA image.
The OTA agent provides an application callback for image verification before invoking this API.
cy_rslt_t cy_ota_storage_verify(cy_ota_storage_context_t *storage_ptr);

7. Validate currently running APP.

cy_ota_storage_validated() - Validates currently executing application and makes it boot image until next upgrade is available.
The application is expected to call this API to execute an image as the boot image until the next upgrade image becomes available.
cy_rslt_t cy_ota_storage_validated(void);

8. Get Application Image information

cy_ota_storage_get_app_info() - Get Application version, Application ID information.
The header of an application image (BOOT/UPGRADE) typically includes the following information.
cy_rslt_t cy_ota_storage_get_app_info(void* file_des, cy_ota_app_info_t *app_info);

Code Snippets

1. Override Default Flash operations API implementation:
Copy flash operation implementations from folder ota-bootloader-abstraction/<version>/configs/COMPONENT_MCUBOOT/flash directory to the top-level code example directory in the project. Change these implementation if required.

/*
* Copy flash operation flash implementations from '<ota-bootloader-abstraction>/configs/COMPONENT_MCUBOOT/flash/' to application space.
* Change default implementation if required.
*/
cy_rslt_t cy_ota_mem_init(void)
{
/*
* Implement code logic to Initialize flash, QSPI flash, or any other external memory type
*/
return CY_RSLT_SUCCESS;
}
cy_rslt_t cy_ota_mem_read(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len)
{
UNUSED_ARG(mem_type);
UNUSED_ARG(addr);
UNUSED_ARG(data);
UNUSED_ARG(len);
/*
* Implement code logic to read from flash, QSPI flash, or any other external memory type
*/
return CY_RSLT_SUCCESS;
}
cy_rslt_t cy_ota_mem_write(cy_ota_mem_type_t mem_type, uint32_t addr, void *data, size_t len)
{
UNUSED_ARG(mem_type);
UNUSED_ARG(addr);
UNUSED_ARG(data);
UNUSED_ARG(len);
/*
* Implement code logic to write data to flash, QSPI flash, or any other external memory type
*/
return CY_RSLT_SUCCESS;
}
cy_rslt_t cy_ota_mem_erase(cy_ota_mem_type_t mem_type, uint32_t addr, size_t len)
{
UNUSED_ARG(mem_type);
UNUSED_ARG(addr);
UNUSED_ARG(len);
/*
* Implement code logic to erase flash, QSPI flash, or any other external memory type
*/
return CY_RSLT_SUCCESS;
}
size_t cy_ota_mem_get_prog_size(cy_ota_mem_type_t mem_type, uint32_t addr)
{
UNUSED_ARG(mem_type);
UNUSED_ARG(addr);
/*
* Implement code logic to get programming page size of flash, QSPI flash, or any other external memory type
*/
return CY_RSLT_SUCCESS;
}
size_t cy_ota_mem_get_erase_size(cy_ota_mem_type_t mem_type, uint32_t addr)
{
UNUSED_ARG(mem_type);
UNUSED_ARG(addr);
/*
* Implement code logic to get sector erase size flash, QSPI flash, or any other external memory type
*/
return CY_RSLT_SUCCESS;
}


2. Registering Storage Interface APIs:
The following code snippet demonstrates an example for initializing the cy_ota_storage_interface_t structure which is required to start the OTA Agent.
This example functions also demonstrates the usage of the OTA Storage Interface APIs for Upgrade image handling (read/write/validate) callback functions.

/* Macro to enable/disable TLS. */
#define ENABLE_TLS (false)
#define HTTP_SERVER "my.httpserver.com"
#define HTTP_SERVER_PORT (80) /* 443 for TLS. */
/* Number of MQTT topic filters. */
#define MQTT_TOPIC_FILTER_NUM (1)
#define MQTT_BROKER "mqtt.broker.com"
#define MQTT_BROKER_PORT (1883) /* (8883) for TLS support. */
/* MQTT topics. */
const char * mqtt_topics[ MQTT_TOPIC_FILTER_NUM ] =
{
"mtb/test/ota/image"
};
/* Root CA Certificate.
Must include the PEM header and footer:
"-----BEGIN CERTIFICATE-----\n" \
".........base64 data.......\n" \
"-----END CERTIFICATE-------\n"
*/
#define ROOT_CA_CERTIFICATE ""
/* Client Certificate.
Must include the PEM header and footer:
"-----BEGIN CERTIFICATE-----\n" \
".........base64 data.......\n" \
"-----END CERTIFICATE-------\n"
*/
#define CLIENT_CERTIFICATE ""
/* Private Key.
Must include the PEM header and footer:
"-----BEGIN RSA PRIVATE KEY-----\n" \
"...........base64 data.........\n" \
"-----END RSA PRIVATE KEY-------\n"
*/
#define CLIENT_KEY ""
/* OTA context. */
static cy_ota_context_ptr ota_context;
/* OTA callback function define. */
cy_ota_callback_results_t ota_callback(cy_ota_cb_struct_t *cb_data);
/* network parameters for OTA. */
cy_ota_network_params_t network_params = { CY_OTA_CONNECTION_UNKNOWN };
/* Parameters for the OTA Agent. */
cy_ota_agent_params_t ota_agent_params =
{
.cb_func = ota_callback, /* Set the value to NULL if the callback function is not used. */
.cb_arg = &ota_context, /* Set the value to NULL if the callback function is not used. */
.reboot_upon_completion = 1 /* Reboot after completing OTA with success. */
};
cy_ota_storage_interface_t ota_interfaces =
{
.ota_file_open = cy_ota_storage_open,
.ota_file_read = cy_ota_storage_read,
.ota_file_write = cy_ota_storage_write,
.ota_file_close = cy_ota_storage_close,
.ota_file_verify = cy_ota_storage_verify,
.ota_file_validate = cy_ota_storage_validated,
.ota_file_get_app_info = cy_ota_storage_get_app_info
};
int main(void)
{
/* BSP Init */
/* Memory Init */
/* Start OTA Agent.*/
result = cy_ota_agent_start(&ota_test_network_params, &ota_test_agent_params, &ota_interfaces, &ota_context);
if (result != CY_RSLT_SUCCESS)
{
printf("Agent start Failed - result: 0x%lx\n", result);
while (true)
{
cy_rtos_delay_milliseconds(10);
}
}
}


ModusToolbox OTA Code Examples

ModusToolbox OTA Example using MQTT: https://github.com/infineon/mtb-example-ota-mqtt
ModusToolbox OTA Update Bluetooth® example: https://github.com/infineon/mtb-example-btstack-freertos-cyw20829-keyboard
MCUboot documentation: https://github.com/JuulLabs-OSS/mcuboot/blob/cypress/docs/design.md