Quality RTOS & Embedded Software

FreeRTOS Extended Maintenance Program (EMP) registration now open.
FreeRTOS-Plus-TCP v3.0.0 released:
Featured FreeRTOS IoT Integrations:
Delta Over-the-Air Updates:
December 2021 Releases:

MCUBoot Demo


NOTE: The following instructions assume a Linux or Windows Subsystem for Linux (WSL) host. WSL installation and setup instructions can be found here.

The demo currently supports the esp32 architecture. The following instructions are specific to this hardware.

The demo consists of MCUBoot booting an application which first disables a bootloader watchdog timer, prints its version number, then confirms itself so it won't be reverted if it's an update. The app proceeds to periodically print "hello world".

The demo also details the application signing and upgrade process, and provides a porting guide for implementing on other SoCs. Finally, use of mcumgr is demonstrated for retrieving image diagnostics, modifying/uploading images, and triggering other board functions from your host PC.

Building and Uploading The Bootloader

  1. Download then enter the repo directory.

    git clone --recurse-submodules https://github.com/FreeRTOS/Lab-Project-FreeRTOS-MCUBoot.git
    cd Lab-Project-FreeRTOS-MCUBoot
  2. Apply the patches required for the bootloader and application.

    git -C lib/mcuboot apply ../../patches/mcuboot.patch
    git -C lib/mcuboot/boot/espressif/hal/esp-idf/ apply ../../../../../../patches/esp-idf.patch
  3. Configure the ESP-IDF tools, then enter the bootloader project directory.

    source lib/mcuboot/boot/espressif/hal/esp-idf/export.sh
    cd proj/espressif/esp32/bootloader
  4. Connect your esp32 and identify it's USB descriptor (for example '/dev/ttyUSB0'), then set this ID.

    export ESPPORT=/dev/<USB>
  5. Decide which, if any, cryptographic verification you want from the following choices:

    • ecdsa-p256
    • rsa-2048
    • rsa-3072
  6. If you want cryptographic image verification, generate the build files as follows, setting SIGNING_SCHEME to be exactly equal to one of the choices above.

    cmake -GNinja -DSIGNING_SCHEME=ecdsa-p256 -B build

    This will generate a private key, of the selected scheme, in the bootloader project directory. The name defaults as mcuboot-private-key.pem. The private key will be used for signing the application images. Meanwhile, the cmake targets take care of embedding the public key in the bootloader, so it can verify the images.

    If you don't want cryptographic image verfication you can omit the SIGNING_SCHEME definition in the command above.

  7. Finally, to upload the bootloader to the board, run the following.

    cmake --build build --target mcuboot-flash

Building and Uploading The Application

After building and flashing the bootloader, proceed with the following. If you're in a new shell session you likely need to re-run the steps above for configuring the IDF toolchain and set ESPPORT.

  1. Enter the application project directory.

    cd proj/espressif/esp32/app
  2. Similarly, when generating build files for the application, you must set SIGNING_SCHEME to match whichever scheme was selected for the Bootloader. Moreover, you must set KEY_PATH to point to the private key generated by the bootloader project. If you opted out of cryptographic image verification in the bootloader, you must similarly omit the SIGNING_SCHEME and KEY_PATH definitions below. Finally, you can set the application version by adding -DAPP_VERSION=X.Y.Z to the command below.

    cmake -DSIGNING_SCHEME=ecdsa-p256 -DKEY_PATH=../bootloader/mcuboot-private-key.pem -GNinja -B build
  3. Build the application.

    cmake --build build --target app
  4. There are two options for uploading the image: directly flashing to the primary image slot, or flashing to the secondary image slot which prompts an upgrade on the subsequent boot if the image has a newer version than that of the primary image. If you don't yet have an image in the primary slot, then directly upload the image there:

    cmake --build build --target mcuboot-app-flash

    When queuing an upgrade, if the secondary image has a newer version than the primary image, the two images will be swapped and the update image will be tentatively booted, and revert upon the subsequent boot if the update image does not confirm itself. Hence the application calls boot_set_confirmed so that it persists as the primary image. Updated images that don't do this will be reverted. To upgrade the image, perform the following:

    cmake --build build --target mcuboot-app-upgrade
  5. Finally, view the output from the device.

    idf.py monitor

Debugging The Application

  1. Configure the ESP-IDF tools in two separate shell sessions using the following commands in each:

    source lib/mcuboot/boot/espressif/hal/esp-idf/export.sh
  2. In one terminal, enter the app directory and start the OpenOCD server.

    cd proj/espressif/esp32/app
    idf.py openocd
  3. In the other terminal, enter the app directory and start the GDB session.

    cd proj/espressif/esp32/app
    idf.py gdb

Serial Boot Mode and MCUMGR Interface

Serial boot mode is enabled by default, but can be disabled by setting MCUBOOT_SERIAL to 0 in mcuboot_config.h located in lib/mcuboot/boot/freertos. The serial boot pin is checked during boot up, and if activated, serial boot mode is entered. For the demo, the serial boot pin is configured as GPIO 5, and is active high. Tying the serial boot pin to VCC will trigger serial mode, tying to GND will skip it. Once serial mode is running, you may interface the board with mcumgr. Installation instructions for mcumgr can be found here.

MCUMGR will communicate with the board via UART pins which, for this demo, are set as GPIO 27 (RX) and GPIO 26 (TX). You can use a USB-to-UART cable such as this one.

Define a connection for mcumgr setting the USB descriptor that corresponds with your USB-to-UART that connects with the device.

mcumgr conn add esp type="serial" connstring="dev=/dev/<USB>,baud=115200,mtu=256"

Tie the boot serial pin to VCC, then reset the board to enter serial boot recovery mode. The board will log that it has entered serial boot mode. You may proceed with the mcumgr interface.

To list images on the device:

mcumgr -c esp image list

To upload an image:

mcumgr -c esp image upload /path/to/mcuboot-image.bin

This expects a signed/formatted MCUBoot image. After building the application, this can be found in its build directory as build/mcuboot-app.bin.

To reset the board:

mcumgr -c esp reset
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.