Mistake on this page? Email us

Porting a new target for Mbed OS

This guide explains how to port Device Management Client using the NUCLEO-F411RE board as an example target.

Configuring the bootloader to support Device Management Client

How the bootloader works with Device Management Client

The bootloader needs to:

  • Know the location of the active application and its header.
  • Know the location of firmware candidates and their headers.
  • Have access to the unique device key if the firmware candidates are stored off-chip.

The bootloader and Update client need to perform security checks and version validations for the firmware update. This means that they need to exchange metadata for the stored and active firmware. The metadata header is the bootloader update interface. Each stage of the boot sequence leading up to and including the application (except the root bootloader) is paired with a metadata header (containing data such as version, size, and hash).

There are two header formats:

  • Internal headers.
  • External headers.

The external format is meant for firmware on external storage, which is assumed to be insecure. Therefore, the external header format contains extra security information to prevent tampering.

The steps to add a new target are:

  1. Choose the location of active header and firmware.
  2. Choose the firmware candidate storage area location and format.

Choose the location of active header and firmware

    +--------------------------+ <-+ End of flash
    |                          |
    +--------------------------+
    |                          |
    |        Active app        |
    |                          |
    +--------------------------+ <-+ application-start-address
    |                          |
    |Active app metadata header|
    |                          |
    +--------------------------+ <-+ update-client.application-details
    |          SOTP_2          |
    +--------------------------+ <-+ sotp-section-2-address
    |          SOTP_1          |
    +--------------------------+ <-+ sotp-section-1-address
    |                          |
    |        Bootloader        |
    |                          |
    +--------------------------+ <-+ 0
  • The bootloader is allocated 32 KB of space at the start of the flash.
  • The Update client uses software one time programming (SOTP) to store a device root of trust. It needs to occupy two erase sectors on the internal flash.
  • The active app metadata header must start on a flash erase boundary (aligned to 16 KB). Here, it starts from 48 KB.
  • The active application must start on a vector table size aligned boundary (aligned to 1 KB). Here, it starts from 65 KB.

Firmware candidate storage area location and format

A storage using a block device is the default implementation for Device Management Client. This uses the Mbed OS block device API to store the candidate firmware and header. This can be on any block device storage supported by Mbed OS. The expected layout is:

    +--------------------------+<-+ End of block device
    |                          |
    +--------------------------+<-+ update-client.storage-size` + `update-client.storage-address
    |                          |
    +--------------------------+
    |                          |
    |   Firmware candidate 1   |
    |                          |
    +--------------------------+
    |   Firmware candidate 1   |
    |     metadata header      |
    +--------------------------+
    |                          |
    +--------------------------+
    |                          |
    |   Firmware candidate 0   |
    |                          |
    +--------------------------+
    |   Firmware candidate 0   |
    |     metadata header      |
    +--------------------------+ <-+ update-client.storage-address
    |                          |
    +--------------------------+ <-+ Start of block device (such as 0x0)

Checking target support by Mbed OS

Check whether the target is already supported by Mbed OS. See the targets.json file in the mbed-os code base. The file is at mbed-os/targets/targets.json. If your target is not listed in the file, follow the instructions in the Mbed OS porting guide. If the bootloader_supported key is set to false or does not exist, enable bootloader support.

If the target is already supported by Mbed OS with the bootloader functionality, continue to Creating the bootloader binary for a new target.

Add bootloader support for Mbed OS

Read the instructions for creating and using the bootloader.

For the NUCLEO-F411RE (ARMCC compiler):

diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct
index c018724..b8e8b03 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct
@@ -1,3 +1,4 @@
+#! armcc -E
 ; Scatter-Loading Description File
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Copyright (c) 2014, STMicroelectronics
@@ -27,10 +28,18 @@
 ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

+#if !defined(MBED_APP_START)
+  #define MBED_APP_START 0x08000000
+#endif
+
+#if !defined(MBED_APP_SIZE)
+  #define MBED_APP_SIZE 0x80000
+#endif
+
 ; STM32F411RE: 512 KB FLASH (0x80000) + 128 KB SRAM (0x20000)
-LR_IROM1 0x08000000 0x80000  {    ; load region size_region
+LR_IROM1 MBED_APP_START MBED_APP_SIZE  {    ; load region size_region

-  ER_IROM1 0x08000000 0x80000  {  ; load address = execution address
+  ER_IROM1 MBED_APP_START MBED_APP_SIZE  {  ; load address = execution address
    *.o (RESET, +First)
    *(InRoot$$Sections)
    .ANY (+RO)

Set MBED_APP_START to point to the starting address of flash memory. MBED_APP_SIZE defines the size of an application image in ROM. This information is available in the target-specific datasheet.

Creating the bootloader binary for a new target

Clone the mbed-bootloader repository and add the new target and macro definitions to mbed_app.json.

When you have added the new target to the configuration file, compile the project.

To add support for NUCLEO-F411RE:

  • Set block device options:
"macros": [
        "ARM_UC_USE_PAL_BLOCKDEVICE=1",
        "MBED_CLOUD_CLIENT_UPDATE_STORAGE=ARM_UCP_FLASHIAP_BLOCKDEVICE"        
        ...
    ],
    "target_overrides": {
        "*": {
            "target.features_remove"                : ["LWIP", "STORAGE"],
            "platform.stdio-baud-rate"              : 115200,
            "platform.stdio-flush-at-exit"          : false,
            "update-client.storage-address"         : "(1024*1024*64)",
            "update-client.storage-size"            : "(1024*1024*2)",
            "update-client.storage-locations"       : 1,
            "update-client.firmware-header-version" : "2"
        },
  • Create a new target. See the table below for an explanation of configuration options:
"target_overrides": {
    "NUCLEO_F411RE": {
            "flash-start-address"               : "0x08000000",
            "flash-size"                        : "(512*1024)",
            "nvstore.area_1_address"            : "(MBED_CONF_APP_FLASH_START_ADDRESS+32*1024)",
            "nvstore.area_1_size"               : "(16*1024)",
            "nvstore.area_2_address"            : "(MBED_CONF_APP_FLASH_START_ADDRESS+48*1024)",
            "nvstore.area_2_size"               : "(16*1024)",
            "update-client.application-details" : "(MBED_CONF_APP_FLASH_START_ADDRESS+64*1024)",
            "application-start-address"         : "(MBED_CONF_APP_FLASH_START_ADDRESS+65*1024)",
            "max-application-size"              : "(MBED_CONF_APP_FLASH_START_ADDRESS + MBED_CONF_APP_FLASH_SIZE - MBED_CONF_APP_APPLICATION_START_ADDRESS)"
        }
}
Option in example Explanation
"flash-start-address" : "0x08000000" Starting address for flash in the target MCU.
"flash-size" : "(512*1024)" Size of the flash in bytes.
"nvstore.area_1_address" : "(MBED_CONF_APP_FLASH_START_ADDRESS+32*1024)" Starting address for section 1. Minimum requirement size is 1 KB. The address must align to flash erase boundary.
"nvstore.area_1_size" : "(16*1024)" Size in bytes for section 1.
"nvstore.area_2_address" : "(MBED_CONF_APP_FLASH_START_ADDRESS+48*1024)" Starting address for section 2. Minimum requirement size is 1 KB. The address must align to flash erase boundary.
"nvstore.area_2_size" : "(16*1024)" Size in bytes for section 2.
"update-client.application-details" : "(MBED_CONF_APP_FLASH_START_ADDRESS+64*1024)" Address to which the metadata header of the active firmware is written. Must align to flash erase boundary.
"application-start-address" : "(MBED_CONF_APP_FLASH_START_ADDRESS+65*1024)" Address at which the application starts. Must align to vector table size boundary and flash write page boundary.
"max-application-size" : "(MBED_CONF_APP_FLASH_START_ADDRESS + MBED_CONF_APP_FLASH_SIZE - MBED_CONF_APP_APPLICATION_START_ADDRESS)" Maximum application size in bytes.

Configuration for storage

Configure the storage settings of Device Management Client for storing device credentials and the firmware update image.

The default configuration for this porting guide is external storage (SD card, external SPI flash) using the FAT filesystem. In this case, no changes are needed for the application configuration.

Configuration for the network interface

Configure the network interface for the selected target.

The default network configuration is in the Mbed target file targets/targets.json. Typical options are null, ETHERNET, WIFI, CELLULAR, or MESH:

    "NUCLEO_F411RE": {
        "overrides": {
            "network-default-interface-type": "ETHERNET"
        }
    },

If the default configuration is set to Wi-Fi, you need to set the Wi-Fi credentials in the application configuration file.

To configure a target with built-in Wi-Fi:

"target_overrides": {
        "*": {
            "nsapi.default-wifi-security"       : "WPA_WPA2",
            "nsapi.default-wifi-ssid"           : "<SSID>",
            "nsapi.default-wifi-password"       : "<PASSWORD>"
        },
        "<YOUR_TARGET>": {
            "target.network-default-interface-type" : "WIFI",
        }
    },

Advanced configuration

To configure add-on boards (Wi-Fi, Thread):

  • ESP8266 Wi-Fi module:
"target_overrides": {
        "*": {
            "esp8266.rx"                        : "D0",
            "esp8266.tx"                        : "D1",
            "esp8266.provide-default"           : true,
            "nsapi.default-wifi-security"       : "WPA_WPA2",
            "nsapi.default-wifi-ssid"           : "<SSID>",
            "nsapi.default-wifi-password"       : "<PASSWORD>"
        },
        "<TARGET>": {
            "target.network-default-interface-type" : "WIFI",
        }
    },
  • Thread configuration using Atmel AT86RF233 RF shield:
"target_overrides": {
        "*": {
            "mbed-client.event-loop-size"                : 32768,
            "mbed-client-pal.pal-dns-api-version"        : 2,
            "nanostack-hal.event_loop_thread_stack_size" : 8192,
            "mbed-mesh-api.thread-config-channel"        : 22,
            "mbed-mesh-api.thread-config-panid"          : "0x0700",
            "nsapi.default-mesh-type"                    : "THREAD",
            "nanostack.configuration"                    : "thread_router",
            "atmel-rf.provide-default"                   : true,
            "target.device_has_add"                      : ["802_15_4_PHY"]
        },
        "<TARGET>": {
            "target.network-default-interface-type" : "MESH",
        }
    }

Read more about networking interfaces and configuration.

Configuration for non-TRNG targets

If there is no true random number generation (TRNG) available for your selected target, you need to provide entropy externally. This means providing entropy through factory provisioning for production devices, and using hardcoded entropy in developer mode through provisioning APIs as demonstrated in the reference example application. However, for a device to use externally provided entropy, you need to appropriately configure TLS. Device Management Client provides such configuration, but you need to enable it in the configuration file.

For example, the NUCLEO-F411RE is a non-TRNG target, so to enable external entropy:

 "NUCLEO_F411RE": {
       "client_app.mbedtls-user-config-file"      : "\"mbedTLSConfig_mbedOS_SW_TRNG.h\"",
       "client_app.pal-user-defined-configuration": "\"sotp_non_trng_config_MbedOS.h\"",
        ...
 }

Porting to Client Lite

The only difference compared to porting to Device Management Client is that when porting to Client Lite, use internal flash instead of SD card or external flash. The following sections detail how to configure the device to use internal flash for Client Lite. All other porting steps are the same as for Device Management Client.

Flash layout using internal flash for Client Lite

The expected layout for Client Lite using internal flash is:

    +--------------------------+ <-+ update-client.storage-address
    |                          |                  +
    |                          |     update-client.storage-size
    |                          |
    |Firmware candidate storage|
    |                          |
    |                          |
    |                          |
    +--------------------------+ <-+ update-client.storage-address
    |                          |
    |                          |
    |                          |
    |        Active app        |
    |                          |
    |                          |
    |                          |
    +--------------------------+ <-+ application-start-address
    |                          |
    |Active app metadata header|
    |                          |
    +--------------------------+ <-+ update-client.application-details
    |        NVSTORE_2         |
    +--------------------------+ <-+ nvstore.area_2_address
    |        NVSTORE_1         |
    +--------------------------+ <-+ nvstore.area_1_address
    |                          |
    |        Bootloader        |
    |                          |
    +--------------------------+ <-+ 0 Start of internal flash

Configuring the bootloader for Client Lite

Choose the appropriate configuration(s) from the /configs folder to modify, and add the configurations for the new target.

This configuration is done for 512 KiB of internal flash beginning at address 0, with 2 KiB erase page size and 4 B write page size. See the table below for an explanation of configuration options:

    "NEW_TARGET": {
        "update-client.application-details" : "(36*1024)",
        "application-start-address"         : "(37*1024)",
        "max-application-size"              : "(MBED_CONF_UPDATE_CLIENT_STORAGE_ADDRESS-MBED_CONF_APP_APPLICATION_START_ADDRESS)",
        "update-client.storage-address"     : "((256+18)*1024)",
        "update-client.storage-size"        : "((256-18)*1024)",
        "update-client.storage-locations"   : 1,
        "update-client.storage-page"        : 4
    }
Option in example Explanation
"update-client.application-details" : "(36*1024)" 32 KiB is saved for bootloader. NVStore uses 4 KiB, so the application details are located at 36 KiB.
"application-start-address" : "(37*1024) 1 KiB is reserved for application details, so application-start-address is 37 KiB.
"max-application-size" : "(MBED_CONF_UPDATE_CLIENT_STORAGE_ADDRESS-MBED_CONF_APP_APPLICATION_START_ADDRESS)" Calculate max-application-size using macros.
"update-client.storage-address" : "((256+18)*1024)" Allocate 237 KiB for the application and rest of the flash, 238 KiB, for update client to store new firmware.
"update-client.storage-page" : 4 This target has 4 B write page size.

Configuring the application for Client Lite

Choose the appropriate configuration(s) from the /configs folder to modify, and add configuration options for the new target.

The application flash configuration must be compatible with the bootloader flash configuration (see above). The NVStore configuration is similar to SOTP in Device Management Client configuration. See the table below for an explanation of configuration options:

    "NEW_TARGET": {
        "target.bootloader_img"             : "</path/to/your/bootloader.bin>",
        "update-client.application-details" : "(36*1024)",
        "update-client.storage-address"     : "((256+18)*1024)",
        "update-client.storage-size"        : "((256-18)*1024)",
        "update-client.storage-locations"   : 1,
        "update-client.storage-page"        : 4,
        "nvstore.area_1_address"            : "(32*1024)",
        "nvstore.area_1_size"               : "(2048)",
        "nvstore.area_2_address"            : "(34*1024)",
        "nvstore.area_2_size"               : "(2048)"
    }
Option in example Explanation
"target.bootloader_img" : "</path/to/your/bootloader.bin>" Path to your bootloader binary that you created earlier. Not mandatory if bootloader is already part of Mbed OS.
"update-client.application-details" : "(36*1024)" Allocate 32 KiB for bootloader. Nvstore uses 4 KiB, so the application details are located at 36 KiB.
"update-client.storage-address" : "((256+18)*1024)" Allocate 237 KiB for the application and rest of the flash, 238 KiB, for Update client to store new firmware.
"update-client.storage-page" : 4 This target has 4 B write page size.
"nvstore.area_1_address" : "(32*1024)" Allocate 4 KiB (2 * 2 KiB) for NVStore after the bootloader.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.