DFU multi-image

The DFU multi-image library provides an API for writing a DFU multi-image package that can be downloaded in chunks of arbitrary size. The DFU multi-image package is a simple archive file that consists of a CBOR-based header that describes contents of the package, followed by a number of updates images, such as firmware images for different MCU cores.

Images included in a DFU multi-image package are identified by numeric identifiers assigned by the user. The library provides a way for the user to register custom functions for writing a single image with a given identifier.

Because the library makes no assumptions about the formats of images included in a written package, it serves as a general-purpose solution for device firmware upgrades. For example, it can be used to upgrade the nRF5340 firmware.

Configuration

To enable the DFU multi-image library, set the CONFIG_DFU_MULTI_IMAGE Kconfig option.

To configure the maximum number of images that the DFU multi-image library is able to process, use the CONFIG_DFU_MULTI_IMAGE_MAX_IMAGE_COUNT Kconfig option.

To enable building the DFU multi-image package that contains commonly used update images, such as the application core firmware, the network core firmware, or MCUboot images, set the CONFIG_DFU_MULTI_IMAGE_PACKAGE_BUILD Kconfig option.

Dependencies

This module uses the following nRF Connect SDK libraries and drivers:

API documentation

Header file: include/dfu/dfu_multi_image.h
Source files: subsys/dfu/dfu_multi_image/src/
group dfu_multi_image

Provides an API for writing DFU Multi Image package.

DFU Multi Image package is a general-purpose update file consisting of a CBOR-based header that describes contents of the package, followed by a number of update components, such as firmware images for different MCU cores. More specifically, the header contains signed numeric identifiers and sizes of included images. The meaning of the identifiers is application-specific, that is, a user is allowed to assign arbitrary identifiers to their images.

A DFU Multi Image package can be built manually using either the Python script located at ‘scripts/bootloader/dfu_multi_image_tool.py’ or the CMake wrapper defined in ‘cmake/dfu_multi_image.cmake’. Additionally, DFU_MULTI_IMAGE_PACKAGE_BUILD and related Kconfig options are available to enable building of a package that includes common update images.

The DFU Multi Image library can be used to process a DFU Multi Image package downloaded onto a device during the DFU process. Its proper usage consists of the following steps:

  1. Call dfu_multi_image_init function to initialize the library’s context.

  2. Call dfu_multi_image_register_writer for each image identifier you would like to extract from the package. Images included in the package for which no corresponding writers have been registered will be ignored.

  3. Pass subsequent downloaded chunks of the package to dfu_multi_image_write function. The chunks must be provided in order. Note that if the function returns an error, no more chunks shall be provided.

  4. Call dfu_multi_image_done function to release open resources and verify that all data declared in the header have been written properly.

Typedefs

typedef int (*dfu_image_open_t)(int image_id, size_t image_size)
typedef int (*dfu_image_write_t)(const uint8_t *chunk, size_t chunk_size)
typedef int (*dfu_image_close_t)(bool success)

Functions

int dfu_multi_image_init(uint8_t *buffer, size_t buffer_size)

Initialize DFU Multi Image library context.

Resets the internal state of the DFU Multi Image library and initializes necessary resources. In particular, the function removes all writers previously registered with the dfu_multi_image_register_writer function.

Parameters:
  • buffer[in] Buffer to store DFU Multi Image header in case it spans multiple chunks of the package. The buffer is only needed until the header is parsed, so the same buffer can be provided to the dfu_target_mcuboot_set_buf function.

  • buffer_size[in] Size of the buffer to store DFU Multi Image header.

Returns:

-EINVAL If the provided buffer is too small.

Returns:

0 On success.

int dfu_multi_image_register_writer(const struct dfu_image_writer *writer)

Register DFU image writer.

Registers functions for opening, writing and closing a single image included in the downloaded DFU Multi Image package.

Parameters:
  • writer[in] Structure that contains the applicable image identifier and functions to be registered.

Returns:

-ENOMEM If the image writer could not be registered due to lack of empty slots.

Returns:

0 On success.

int dfu_multi_image_write(size_t offset, const uint8_t *chunk, size_t chunk_size)

Write subsequent DFU Multi Image package chunk.

Called to consume a subsequent chunk of the DFU Multi Image package. The initial bytes of the package contain a header that allows the library to learn offsets of particular images within the entire package. After the header is parsed, the registered image writers are used to store the image data.

The package chunks must be provided in order.

When an image for which no writer has been registered is found in the package, the library may decide to skip ahead the image. For that reason, a user of the function must provide the offset argument to validate the chunk’s position against the current write position and potentially drop the bytes that are not needed anymore.

A user shall NOT write any more chunks after any write results in a failure.

Parameters:
  • offset[in] Offset of the chunk within the entire package.

  • chunk[in] Pointer to the chunk’s data.

  • chunk_size[in] Size of the chunk.

Return values:

-ESPIPE – If offset is bigger than expected which may indicate a data gap or writing more data than declared in the package header.

Returns:

negative On other failure.

Returns:

0 On success.

size_t dfu_multi_image_offset(void)

Returns DFU Multi Image package write position.

Returns:

Offset of the next needed package chunk in bytes.

int dfu_multi_image_done(bool success)

Complete DFU Multi Image package write.

Close an open image writer if such exists. Additionally, if success argument is true, the function validates that all images listed in the package header have been fully written.

Parameters:
  • success[in] Indicates that a user expects all the package contents to have been written successfully.

Returns:

-ESPIPE If success and not all package contents have been written yet.

Returns:

negative On other failure.

Returns:

0 On success.

struct dfu_image_writer
#include <dfu_multi_image.h>

User-provided functions for writing a single image from DFU Multi Image package.

Public Members

int image_id

Identifier of the applicable image.

dfu_image_open_t open

Function called before writing the first byte of the applicable image.

The function is indirectly called by dfu_multi_image_write and in the case of failure the error code is propagated and returned from the latter function.

Return:

negative On failure.

Return:

0 On success.

dfu_image_write_t write

Function called to write a subsequent chunk of the applicable image.

The function is indirectly called by dfu_multi_image_write and in the case of failure the error code is propagated and returned from the latter function.

Return:

negative On failure.

Return:

0 On success.

dfu_image_close_t close

Function called after writing the last byte of the applicable image.

The function is indirectly called by dfu_multi_image_write or dfu_multi_image_done and in the case of failure the error code is propagated and returned from the latter function.

Return:

negative On failure.

Return:

0 On success.