Device Firmware Upgrade

Overview

The Device Firmware Upgrade subsystem provides the necessary frameworks to upgrade the image of a Zephyr-based application at run time. It currently consists of two different modules:

The DFU subsystem deals with image management, but not with the transport or management protocols themselves required to send the image to the target device. For information on these protocols and frameworks please refer to the Device Management section.

Flash Image

The flash image API as part of the Device Firmware Upgrade (DFU) subsystem provides an abstraction on top of Flash Stream to simplify writing firmware image chunks to flash.

API Reference

group flash_img_api

Abstraction layer to write firmware images to flash.

Functions

int flash_img_init_id(struct flash_img_context *ctx, uint8_t area_id)

Initialize context needed for writing the image to the flash.

Parameters:
  • ctx – context to be initialized

  • area_id – flash area id of partition where the image should be written

Returns:

0 on success, negative errno code on fail

int flash_img_init(struct flash_img_context *ctx)

Initialize context needed for writing the image to the flash.

Parameters:
  • ctx – context to be initialized

Returns:

0 on success, negative errno code on fail

size_t flash_img_bytes_written(struct flash_img_context *ctx)

Read number of bytes of the image written to the flash.

Parameters:
  • ctx – context

Returns:

Number of bytes written to the image flash.

int flash_img_buffered_write(struct flash_img_context *ctx, const uint8_t *data, size_t len, bool flush)

Process input buffers to be written to the image slot 1.

flash memory in single blocks. Will store remainder between calls.

A final call to this function with flush set to true will write out the remaining block buffer to flash. Since flash is written to in blocks, the contents of flash from the last byte written up to the next multiple of CONFIG_IMG_BLOCK_BUF_SIZE is padded with 0xff.

Parameters:
  • ctx – context

  • data – data to write

  • len – Number of bytes to write

  • flush – when true this forces any buffered data to be written to flash

Returns:

0 on success, negative errno code on fail

int flash_img_check(struct flash_img_context *ctx, const struct flash_img_check *fic, uint8_t area_id)

Verify flash memory length bytes integrity from a flash area.

The start point is indicated by an offset value.

The function is enabled via CONFIG_IMG_ENABLE_IMAGE_CHECK Kconfig options.

Parameters:
  • ctx[in] context.

  • fic[in] flash img check data.

  • area_id[in] flash area id of partition where the image should be verified.

Returns:

0 on success, negative errno code on fail

struct flash_img_context
#include <flash_img.h>
struct flash_img_check
#include <flash_img.h>

Structure for verify flash region integrity.

Match vector length is fixed and depends on size from hash algorithm used to verify flash integrity. The current available algorithm is SHA-256.

Public Members

size_t clen

Match vector data.

MCUBoot API

The MCUboot API is provided to get version information and boot status of application images. It allows to select application image and boot type for the next boot.

API Reference

group mcuboot_api

MCUboot public API for MCUboot control of image boot process.

Defines

BOOT_SWAP_TYPE_NONE

Attempt to boot the contents of slot 0.

BOOT_SWAP_TYPE_TEST

Swap to slot 1.

Absent a confirm command, revert back on next boot.

BOOT_SWAP_TYPE_PERM

Swap to slot 1, and permanently switch to booting its contents.

BOOT_SWAP_TYPE_REVERT

Swap back to alternate slot.

A confirm changes this state to NONE.

BOOT_SWAP_TYPE_FAIL

Swap failed because image to be run is not valid.

BOOT_IMG_VER_STRLEN_MAX
BOOT_UPGRADE_TEST

Boot upgrade request modes.

BOOT_UPGRADE_PERMANENT

Functions

int boot_read_bank_header(uint8_t area_id, struct mcuboot_img_header *header, size_t header_size)

Read the MCUboot image header information from an image bank.

This attempts to parse the image header, From the start of the area_id image.

Parameters:
  • area_idflash_area ID of image bank which stores the image.

  • header – On success, the returned header information is available in this structure.

  • header_size – Size of the header structure passed by the caller. If this is not large enough to contain all of the necessary information, an error is returned.

Returns:

Zero on success, a negative value on error.

bool boot_is_img_confirmed(void)

Check if the currently running image is confirmed as OK.

MCUboot can perform “test” upgrades. When these occur, a new firmware image is installed and booted, but the old version will be reverted at the next reset unless the new image explicitly marks itself OK.

This routine can be used to check if the currently running image has been marked as OK.

Returns:

True if the image is confirmed as OK, false otherwise.

int boot_write_img_confirmed(void)

Marks the currently running image as confirmed.

This routine attempts to mark the currently running firmware image as OK, which will install it permanently, preventing MCUboot from reverting it for an older image at the next reset.

This routine is safe to call if the current image has already been confirmed. It will return a successful result in this case.

Returns:

0 on success, negative errno code on fail.

int boot_write_img_confirmed_multi(int image_index)

Marks the image with the given index in the primary slot as confirmed.

This routine attempts to mark the firmware image in the primary slot as OK, which will install it permanently, preventing MCUboot from reverting it for an older image at the next reset.

This routine is safe to call if the current image has already been confirmed. It will return a successful result in this case.

Parameters:
  • image_index – Image pair index.

Returns:

0 on success, negative errno code on fail.

int mcuboot_swap_type(void)

Determines the action, if any, that mcuboot will take on the next reboot.

Returns:

a BOOT_SWAP_TYPE_[…] constant on success, negative errno code on fail.

int mcuboot_swap_type_multi(int image_index)

Determines the action, if any, that mcuboot will take on the next reboot.

Parameters:
  • image_index – Image pair index.

Returns:

a BOOT_SWAP_TYPE_[…] constant on success, negative errno code on fail.

int boot_request_upgrade(int permanent)

Marks the image in slot 1 as pending.

On the next reboot, the system will perform a boot of the slot 1 image.

Parameters:
  • permanent – Whether the image should be used permanently or only tested once: BOOT_UPGRADE_TEST=run image once, then confirm or revert. BOOT_UPGRADE_PERMANENT=run image forever.

Returns:

0 on success, negative errno code on fail.

int boot_request_upgrade_multi(int image_index, int permanent)

Marks the image with the given index in the secondary slot as pending.

On the next reboot, the system will perform a boot of the secondary slot image.

Parameters:
  • image_index – Image pair index.

  • permanent – Whether the image should be used permanently or only tested once: BOOT_UPGRADE_TEST=run image once, then confirm or revert. BOOT_UPGRADE_PERMANENT=run image forever.

Returns:

0 on success, negative errno code on fail.

int boot_erase_img_bank(uint8_t area_id)

Erase the image Bank.

Parameters:
  • area_idflash_area ID of image bank to be erased.

Returns:

0 on success, negative errno code on fail.

ssize_t boot_get_area_trailer_status_offset(uint8_t area_id)

Get the offset of the status in the image bank.

Parameters:
  • area_idflash_area ID of image bank to get the status offset

Returns:

a positive offset on success, negative errno code on fail

ssize_t boot_get_trailer_status_offset(size_t area_size)

Get the offset of the status from an image bank size.

Parameters:
  • area_size – size of image bank

Returns:

offset of the status. When negative the status will not fit the given size

struct mcuboot_img_sem_ver
#include <mcuboot.h>

MCUboot image header representation for image version.

The header for an MCUboot firmware image contains an embedded version number, in semantic versioning format. This structure represents the information it contains.

struct mcuboot_img_header_v1
#include <mcuboot.h>

Model for the MCUboot image header as of version 1.

This represents the data present in the image header, in version 1 of the header format.

Some information present in the header but not currently relevant to applications is omitted.

Public Members

uint32_t image_size

The size of the image, in bytes.

struct mcuboot_img_sem_ver sem_ver

The image version.

struct mcuboot_img_header
#include <mcuboot.h>

Model for the MCUBoot image header.

This contains the decoded image header, along with the major version of MCUboot that the header was built for.

(The MCUboot project guarantees that incompatible changes to the image header will result in major version changes to the bootloader itself, and will be detectable in the persistent representation of the header.)

Public Members

uint32_t mcuboot_version

The version of MCUboot the header is built for.

The value 1 corresponds to MCUboot versions 1.x.y.

struct mcuboot_img_header_v1 v1

Header information for MCUboot version 1.

union mcuboot_img_header.[anonymous] h

The header information.

It is only valid to access fields in the union member corresponding to the mcuboot_version field above.

Bootloaders

MCUboot

Zephyr is directly compatible with the open source, cross-RTOS MCUboot boot loader. It interfaces with MCUboot and is aware of the image format required by it, so that Device Firmware Upgrade is available when MCUboot is the boot loader used with Zephyr. The source code itself is hosted in the MCUboot GitHub Project page.

In order to use MCUboot with Zephyr you need to take the following into account:

  1. You will need to define the flash partitions required by MCUboot; see Flash map for details.

  2. You will have to specify your flash partition as the chosen code partition

/ {
   chosen {
      zephyr,code-partition = &slot0_partition;
   };
};
  1. Your application’s .conf file needs to enable the CONFIG_BOOTLOADER_MCUBOOT Kconfig option in order for Zephyr to be built in an MCUboot-compatible manner

  2. You need to build and flash MCUboot itself on your device

  3. You might need to take precautions to avoid mass erasing the flash and also to flash the Zephyr application image at the correct offset (right after the bootloader)

More detailed information regarding the use of MCUboot with Zephyr can be found in the MCUboot with Zephyr documentation page on the MCUboot website.