Skip to content

Commit 1600b12

Browse files
dfu: Add custom device update
Adds a custom device update option to the DFU subsystem Signed-off-by: Mathijs Meulendijks <mathijs.meulendijks@unitial.tech>
1 parent d3df483 commit 1600b12

File tree

5 files changed

+123
-1
lines changed

5 files changed

+123
-1
lines changed

doc/nrf/libraries/dfu/dfu_target.rst

+9
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ The DFU target library supports the following types of firmware upgrades:
4949
* Modem delta upgrades
5050
* Full modem firmware upgrades
5151
* SUIT-style upgrades
52+
* Custom upgrades
5253

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

171+
Custom upgrades
172+
---------------
173+
174+
This firmware upgrade supports custom updates for external peripherals or other custom firmware.
175+
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.
176+
177+
170178
Configuration
171179
*************
172180

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

197206
Maintaining writing progress after reboot
198207
=========================================

include/dfu/dfu_target.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ enum dfu_target_image_type {
3838
DFU_TARGET_IMAGE_TYPE_SMP = 8,
3939
/** SUIT Envelope */
4040
DFU_TARGET_IMAGE_TYPE_SUIT = 16,
41+
/** Custom update implementation */
42+
DFU_TARGET_IMAGE_TYPE_CUSTOM = 128,
4143
/** Any application image type */
4244
DFU_TARGET_IMAGE_TYPE_ANY_APPLICATION = DFU_TARGET_IMAGE_TYPE_MCUBOOT,
4345
/** Any modem image */
@@ -46,7 +48,7 @@ enum dfu_target_image_type {
4648
/** Any DFU image type */
4749
DFU_TARGET_IMAGE_TYPE_ANY =
4850
(DFU_TARGET_IMAGE_TYPE_MCUBOOT | DFU_TARGET_IMAGE_TYPE_MODEM_DELTA |
49-
DFU_TARGET_IMAGE_TYPE_FULL_MODEM),
51+
DFU_TARGET_IMAGE_TYPE_FULL_MODEM | DFU_TARGET_IMAGE_TYPE_CUSTOM),
5052
};
5153

5254
enum dfu_target_evt_id {

include/dfu/dfu_target_custom.h

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/**
8+
* @file dfu_target_custom.h
9+
* @defgroup dfu_target_custom Custom DFU Target
10+
* @{
11+
* @brief Custom DFU (Device Firmware Update) target implementation.
12+
*
13+
* This file contains the function declarations for a custom DFU target implementation.
14+
* It provides function prototypes for identifying, initializing, writing, and finalizing a custom
15+
* firmware update process.
16+
*/
17+
18+
#ifndef DFU_TARGET_CUSTOM_H__
19+
#define DFU_TARGET_CUSTOM_H__
20+
21+
#include <dfu/dfu_target.h>
22+
#include <stddef.h>
23+
24+
#ifdef __cplusplus
25+
extern "C" {
26+
#endif
27+
/**
28+
* @brief Check if the provided buffer contains a custom firmware image.
29+
*
30+
* @param[in] buf Pointer to the buffer containing the potential firmware image.
31+
* @retval true if the buffer contains a valid custom firmware image, false otherwise.
32+
*/
33+
bool dfu_target_custom_identify(const void *const buf);
34+
35+
/**
36+
* @brief Initialize the custom DFU target.
37+
*
38+
* @param[in] file_size Size of the firmware file to be written.
39+
* @param[in] img_num Image number for multi-image DFU.
40+
* @param[in] cb Callback function to be called during the DFU process.
41+
* @retval 0 on success, negative errno code on failure.
42+
*/
43+
int dfu_target_custom_init(size_t file_size, int img_num, dfu_target_callback_t cb);
44+
45+
/**
46+
* @brief Get the current write offset for the custom DFU target.
47+
*
48+
* @param[out] offset Pointer to store the current write offset.
49+
* @retval 0 on success, negative errno code on failure.
50+
*/
51+
int dfu_target_custom_offset_get(size_t *offset);
52+
53+
/**
54+
* @brief Write data to the custom DFU target.
55+
*
56+
* @param[in] buf Pointer to the buffer containing the data to be written.
57+
* @param[in] len Length of the data to be written.
58+
* @retval 0 on success, negative errno code on failure.
59+
*/
60+
int dfu_target_custom_write(const void *const buf, size_t len);
61+
62+
/**
63+
* @brief Release resources and finalize the custom DFU process if successful.
64+
*
65+
* @param[in] successful True if the DFU process was successful, false otherwise.
66+
* @retval 0 on success, negative errno code on failure.
67+
*/
68+
int dfu_target_custom_done(bool successful);
69+
70+
/**
71+
* @brief Schedule an update for the custom DFU target.
72+
*
73+
* @param[in] img_num Image number for multi-image DFU.
74+
* @retval 0 on success, negative errno code on failure.
75+
*/
76+
int dfu_target_custom_schedule_update(int img_num);
77+
78+
/**
79+
* @brief Release resources and erase the download area.
80+
*
81+
* Cancel any ongoing updates.
82+
*
83+
* @retval 0 on success, negative errno code on failure.
84+
*/
85+
int dfu_target_custom_reset(void);
86+
87+
#ifdef __cplusplus
88+
}
89+
#endif
90+
91+
#endif /* DFU_TARGET_SUIT_H__ */
92+
/**@} */

subsys/dfu/dfu_target/Kconfig

+5
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ config DFU_TARGET_REBOOT_RESET_DELAY_MS
152152

153153
endif # DFU_TARGET_SUIT
154154

155+
config DFU_TARGET_CUSTOM
156+
bool "Custom application-controlled update support"
157+
help
158+
Enable support for custom updates using DFU target
159+
155160
module=DFU_TARGET
156161
module-dep=LOG
157162
module-str=Device Firmware Upgrade

subsys/dfu/dfu_target/src/dfu_target.c

+14
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ DEF_DFU_TARGET(smp);
3838
#include "dfu/dfu_target_suit.h"
3939
DEF_DFU_TARGET(suit);
4040
#endif
41+
#ifdef CONFIG_DFU_TARGET_CUSTOM
42+
#include "dfu/dfu_target_custom.h"
43+
DEF_DFU_TARGET(custom);
44+
#endif
4145

4246
#define MIN_SIZE_IDENTIFY_BUF 32
4347

@@ -65,6 +69,11 @@ enum dfu_target_image_type dfu_target_img_type(const void *const buf, size_t len
6569
if (dfu_target_full_modem_identify(buf)) {
6670
return DFU_TARGET_IMAGE_TYPE_FULL_MODEM;
6771
}
72+
#endif
73+
#ifdef CONFIG_DFU_TARGET_CUSTOM
74+
if (dfu_target_custom_identify(buf)) {
75+
return DFU_TARGET_IMAGE_TYPE_CUSTOM;
76+
}
6877
#endif
6978
LOG_ERR("No supported image type found");
7079
return DFU_TARGET_IMAGE_TYPE_NONE;
@@ -113,6 +122,11 @@ int dfu_target_init(int img_type, int img_num, size_t file_size, dfu_target_call
113122
new_target = &dfu_target_suit;
114123
}
115124
#endif
125+
#ifdef CONFIG_DFU_TARGET_CUSTOM
126+
if (img_type == DFU_TARGET_IMAGE_TYPE_CUSTOM) {
127+
new_target = &dfu_target_custom;
128+
}
129+
#endif
116130

117131
if (new_target == NULL) {
118132
LOG_ERR("Unknown image type");

0 commit comments

Comments
 (0)