Skip to content

Commit

Permalink
dfu: Add custom device update
Browse files Browse the repository at this point in the history
Adds a custom device update option to the DFU subsystem
Signed-off-by: Mathijs Meulendijks <mathijs.meulendijks@unitial.tech>
  • Loading branch information
mathijsmeulendijks committed Nov 22, 2024
1 parent c01d938 commit 99e1ebd
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 1 deletion.
9 changes: 9 additions & 0 deletions doc/nrf/libraries/dfu/dfu_target.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ The DFU target library supports the following types of firmware upgrades:
* Modem delta upgrades
* Full modem firmware upgrades
* SUIT-style upgrades
* Custom upgrades

MCUboot-style upgrades
----------------------
Expand Down Expand Up @@ -167,6 +168,13 @@ When all image data transfers are completed, the application using the DFU targe
The application must schedule the upgrade of all images at once using the :c:func:`dfu_target_schedule_update` function.
During this operation, the manifests stored in the ``dfu_partition`` partition will be processed.

Custom upgrades
-------------------

This firmware upgrade supports custom updates for external peripherals or other custom firmware.
To use this feature, the application must implement the custom upgrade logic by applying the functions defined in the :file:`include/dfu/dfu_target_custom.h` file.


Configuration
*************

Expand All @@ -193,6 +201,7 @@ You can disable support for specific DFU targets using the following options:
* :kconfig:option:`CONFIG_DFU_TARGET_MCUBOOT`
* :kconfig:option:`CONFIG_DFU_TARGET_MODEM_DELTA`
* :kconfig:option:`CONFIG_DFU_TARGET_FULL_MODEM`
* :kconfig:option:`CONFIG_DFU_TARGET_CUSTOM`

Maintaining writing progress after reboot
=========================================
Expand Down
4 changes: 3 additions & 1 deletion include/dfu/dfu_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ enum dfu_target_image_type {
DFU_TARGET_IMAGE_TYPE_SMP = 8,
/** SUIT Envelope */
DFU_TARGET_IMAGE_TYPE_SUIT = 16,
/** Custom update implementation, e.g. for external MCU */
DFU_TARGET_IMAGE_TYPE_CUSTOM = 32,
/** Any application image type */
DFU_TARGET_IMAGE_TYPE_ANY_APPLICATION = DFU_TARGET_IMAGE_TYPE_MCUBOOT,
/** Any modem image */
Expand All @@ -46,7 +48,7 @@ enum dfu_target_image_type {
/** Any DFU image type */
DFU_TARGET_IMAGE_TYPE_ANY =
(DFU_TARGET_IMAGE_TYPE_MCUBOOT | DFU_TARGET_IMAGE_TYPE_MODEM_DELTA |
DFU_TARGET_IMAGE_TYPE_FULL_MODEM),
DFU_TARGET_IMAGE_TYPE_FULL_MODEM | DFU_TARGET_IMAGE_TYPE_CUSTOM),
};

enum dfu_target_evt_id {
Expand Down
92 changes: 92 additions & 0 deletions include/dfu/dfu_target_custom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/**
* @file dfu_target_custom.h
* @defgroup dfu_target_custom Custom DFU Target
* @{
* @brief Custom DFU (Device Firmware Update) target implementation.
*
* This file contains the function declarations for a custom DFU target implementation.
* It provides function prototypess for identifying, initializing, writing, and finalizing a custom
* firmware update process.
*/

#ifndef DFU_TARGET_CUSTOM_H__
#define DFU_TARGET_CUSTOM_H__

#include <dfu/dfu_target.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Identifies if the provided buffer contains a custom firmware image.
*
* @param[in] buf Pointer to the buffer containing the potential firmware image.
* @retval true if the buffer contains a valid custom firmware image, false otherwise.
*/
bool dfu_target_custom_identify(const void *const buf);

/**
* @brief Initializes the custom DFU target.
*
* @param[in] file_size Size of the firmware file to be written.
* @param[in] img_num Image number for multi-image DFU.
* @param[in] cb Callback function to be called during the DFU process.
* @retval 0 on success, negative errno code on failure.
*/
int dfu_target_custom_init(size_t file_size, int img_num, dfu_target_callback_t cb);

/**
* @brief Gets the current write offset for the custom DFU target.
*
* @param[out] offset Pointer to store the current write offset.
* @retval 0 on success, negative errno code on failure.
*/
int dfu_target_custom_offset_get(size_t *offset);

/**
* @brief Writes data to the custom DFU target.
*
* @param[in] buf Pointer to the buffer containing the data to be written.
* @param[in] len Length of the data to be written.
* @retval 0 on success, negative errno code on failure.
*/
int dfu_target_custom_write(const void *const buf, size_t len);

/**
* @brief Releases resources and finalizes the custom DFU process if successful.
*
* @param[in] successful true if the DFU process was successful, false otherwise.
* @retval 0 on success, negative errno code on failure.
*/
int dfu_target_custom_done(bool successful);

/**
* @brief Schedules an update for the custom DFU target.
*
* @param[in] img_num Image number for multi-image DFU.
* @retval 0 on success, negative errno code on failure.
*/
int dfu_target_custom_schedule_update(int img_num);

/**
* @brief Release resources and erase the download area.
*
* Cancel any ongoing updates.
*
* @retval 0 on success, negative errno code on failure.
*/
int dfu_target_custom_reset(void);

#ifdef __cplusplus
}
#endif

#endif /* DFU_TARGET_SUIT_H__ */
/**@} */
6 changes: 6 additions & 0 deletions subsys/dfu/dfu_target/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ config DFU_TARGET_REBOOT_RESET_DELAY_MS

endif # DFU_TARGET_SUIT

config DFU_TARGET_CUSTOM
bool "Custom application controlled update support"
default n
help
Enable support for custom updates using DFU target

module=DFU_TARGET
module-dep=LOG
module-str=Device Firmware Upgrade
Expand Down
14 changes: 14 additions & 0 deletions subsys/dfu/dfu_target/src/dfu_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ DEF_DFU_TARGET(smp);
#include "dfu/dfu_target_suit.h"
DEF_DFU_TARGET(suit);
#endif
#ifdef CONFIG_DFU_TARGET_CUSTOM
#include "dfu/dfu_target_custom.h"
DEF_DFU_TARGET(custom);
#endif

#define MIN_SIZE_IDENTIFY_BUF 32

Expand Down Expand Up @@ -65,6 +69,11 @@ enum dfu_target_image_type dfu_target_img_type(const void *const buf, size_t len
if (dfu_target_full_modem_identify(buf)) {
return DFU_TARGET_IMAGE_TYPE_FULL_MODEM;
}
#endif
#ifdef CONFIG_DFU_TARGET_CUSTOM
if (dfu_target_custom_identify(buf)) {
return DFU_TARGET_IMAGE_TYPE_CUSTOM;
}
#endif
LOG_ERR("No supported image type found");
return DFU_TARGET_IMAGE_TYPE_NONE;
Expand Down Expand Up @@ -113,6 +122,11 @@ int dfu_target_init(int img_type, int img_num, size_t file_size, dfu_target_call
new_target = &dfu_target_suit;
}
#endif
#ifdef CONFIG_DFU_TARGET_CUSTOM
if (img_type == DFU_TARGET_IMAGE_TYPE_CUSTOM) {
new_target = &dfu_target_custom;
}
#endif

if (new_target == NULL) {
LOG_ERR("Unknown image type");
Expand Down

0 comments on commit 99e1ebd

Please sign in to comment.