Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/infuse/dfu/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ extern "C" {
*
* @param fa Flash area to erase (must be already opened)
* @param image_len Length of image
* @param progress_callback Optional progress callback
* @param mcuboot_trailer Erase space for MCUBoot trailer
*
* @retval 0 On success
* @retval -errno Error code from @a flash_area_erase on failure
*/
int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len, bool mcuboot_trailer);
int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len,
void (*progress_callback)(uint32_t offset), bool mcuboot_trailer);

/**
* @brief Prepare the nRF91 modem for a delta image upgrade
Expand Down
12 changes: 11 additions & 1 deletion subsys/dfu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,22 @@ config INFUSE_DFU_HELPERS
depends on FLASH_PAGE_LAYOUT
default y if MCUBOOT_IMG_MANAGER || INFUSE_RPC_COMMAND_BT_FILE_COPY_BASIC || SOC_SERIES_BSIM_NRFXX

if INFUSE_DFU_HELPERS

config INFUSE_DFU_HELPERS_ERASE_CHUNK_SIZE
int "Number of bytes to erase in each call to `flash_area_flatten`"
default 65536
help
Erasing a large flash area can take a long time, break up large erases into
chunks of this size to provide an opportunity for watchdogs to be fed.

config INFUSE_DFU_EXFAT
bool "Upgrade application images from an exFAT filesystem"
depends on INFUSE_DFU_HELPERS
depends on MCUBOOT_IMG_MANAGER
depends on DATA_LOGGER_EXFAT
default y
help
Enable functions to automate the process of upgrading firmware from a
/dfu folder on a mounted filesystem.

endif # INFUSE_DFU_HELPERS
2 changes: 1 addition & 1 deletion subsys/dfu/dfu_exfat.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ int dfu_exfat_app_upgrade_copy(const struct device *dev, struct infuse_version u
}

/* Erase output area */
if (infuse_dfu_image_erase(fa, fno.fsize, true) != 0) {
if (infuse_dfu_image_erase(fa, fno.fsize, NULL, true) != 0) {
rc = -EIO;
goto close_area;
}
Expand Down
28 changes: 23 additions & 5 deletions subsys/dfu/dfu_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
#endif /* CONFIG_NRF_MODEM_LIB */

/* Implementation taken from zephyr_img_mgmt.c */
int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len, bool mcuboot_trailer)
int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len,
void (*progress_callback)(uint32_t offset), bool mcuboot_trailer)
{
const struct device *dev = flash_area_get_device(fa);
struct flash_pages_info page;
size_t off __maybe_unused;
size_t remaining;
size_t max_chunk;
size_t chunk_size;
size_t off;
off_t page_offset;
size_t erase_size;
int rc;
Expand All @@ -45,9 +49,23 @@ int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len, bool m
erase_size = page.start_offset + page.size - fa->fa_off;

/* Perform the erase */
rc = flash_area_flatten(fa, 0, erase_size);
if (rc < 0) {
return rc;
max_chunk = progress_callback ? CONFIG_INFUSE_DFU_HELPERS_ERASE_CHUNK_SIZE : erase_size;
remaining = erase_size;
off = 0;
while (remaining) {
/* Erase next chunk */
chunk_size = MIN(max_chunk, remaining);
printk("Erasing %6d at 0x%08X\n", off, chunk_size);
rc = flash_area_flatten(fa, off, chunk_size);
if (rc < 0) {
return rc;
}
off += chunk_size;
remaining -= chunk_size;
/* Run provided callback */
if (progress_callback) {
progress_callback(off);
}
}

if (!mcuboot_trailer) {
Expand Down
14 changes: 7 additions & 7 deletions subsys/rpc/commands/common_file_actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ LOG_MODULE_DECLARE(rpc_server);

#if defined(SUPPORT_APP_IMG) || defined(SUPPORT_APP_CPATCH) || defined(SUPPORT_FILE_COPY)

static void cpatch_watchdog(uint32_t progress_offset)
{
rpc_server_watchdog_feed();
}

static int flash_area_check_and_erase(struct rpc_common_file_actions_ctx *ctx, uint8_t partition_id,
uint32_t length, uint32_t crc, bool mcuboot_trailer)
{
Expand Down Expand Up @@ -71,7 +76,7 @@ static int flash_area_check_and_erase(struct rpc_common_file_actions_ctx *ctx, u
length = ctx->fa->fa_size;
}
/* Erase space for image */
rc = infuse_dfu_image_erase(ctx->fa, length, mcuboot_trailer);
rc = infuse_dfu_image_erase(ctx->fa, length, cpatch_watchdog, mcuboot_trailer);
if (rc != 0) {
/* Close flash area */
(void)flash_area_close(ctx->fa);
Expand Down Expand Up @@ -219,11 +224,6 @@ int rpc_common_file_actions_write(struct rpc_common_file_actions_ctx *ctx, uint3

#ifdef SUPPORT_APP_CPATCH

static void cpatch_watchdog(uint32_t progress_offset)
{
rpc_server_watchdog_feed();
}

static int validate_cpatch(struct rpc_common_file_actions_ctx *ctx)
{
const struct flash_area *fa_original;
Expand Down Expand Up @@ -263,7 +263,7 @@ static int finish_cpatch(struct rpc_common_file_actions_ctx *ctx)

LOG_INF("Erasing %d bytes of secondary partition", header.output_file.length);
/* Erase space for image */
rc = infuse_dfu_image_erase(fa_output, header.output_file.length, true);
rc = infuse_dfu_image_erase(fa_output, header.output_file.length, cpatch_watchdog, true);
if (rc < 0) {
goto cleanup;
}
Expand Down