Skip to content

Commit

Permalink
[nrf fromlist] susbys/dfu/img_util: refined ERASE PROGRESSIVELY imple…
Browse files Browse the repository at this point in the history
…mentation

Moved MCUboot trailer's status erase ahead any write operation,
which is step which helps with addition of support for devices
don't require explicit pager erase.
For these kind of devices flattening of mcuboot image status in
the trailer was introduced.

Upstream PR: zephyrproject-rtos/zephyr#79152

Signed-off-by: Andrzej Puzdrowski <[email protected]>
  • Loading branch information
nvlsianpu committed Oct 17, 2024
1 parent b10af16 commit a0a34c2
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 29 deletions.
3 changes: 1 addition & 2 deletions subsys/dfu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ config IMG_BLOCK_BUF_SIZE

config IMG_ERASE_PROGRESSIVELY
bool "Erase flash progressively when receiving new firmware"
select STREAM_FLASH_ERASE
depends on FLASH_HAS_EXPLICIT_ERASE
select STREAM_FLASH_ERASE if FLASH_HAS_EXPLICIT_ERASE
help
If enabled, flash is erased as necessary when receiving new firmware,
instead of erasing the whole image slot at once. This is necessary
Expand Down
88 changes: 61 additions & 27 deletions subsys/dfu/img_util/flash_img.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,44 +43,78 @@ BUILD_ASSERT((CONFIG_IMG_BLOCK_BUF_SIZE % FLASH_WRITE_BLOCK_SIZE == 0),
"FLASH_WRITE_BLOCK_SIZE");
#endif

static int scramble_mcuboot_trailer(struct flash_img_context *ctx)
{
int rc = 0;

#ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
if (stream_flash_bytes_written(&ctx->stream) == 0) {
off_t toff = boot_get_trailer_status_offset(ctx->flash_area->fa_size);
off_t offset;
size_t size;
const struct flash_parameters *fparams =
flash_get_parameters(flash_area_get_device(ctx->flash_area));
#ifdef CONFIG_STREAM_FLASH_ERASE
/* for erasable devices prgressive-erase works only along with
* CONFIG_STREAM_FLASH_ERASE option.
*/
if (flash_params_get_erase_cap(fparams) & FLASH_ERASE_C_EXPLICIT) {
/* On devices with explicit erase we are aligning to page
* layout.
*/
struct flash_pages_info info;

rc = flash_get_page_info_by_offs(flash_area_get_device(ctx->flash_area),
toff, &info);
if (rc != 0) {
return rc;
}
offset = info.start_offset;
size = info.size;

} else
#endif
{
/* On devices with no erase, we are aligning to write block
* size.
*/
offset = (toff + fparams->write_block_size - 1) &
~(fparams->write_block_size - 1);
/* No alignment correction needed here, offset is corrected already
* and, size should be aligned.
*/
size = ctx->flash_area->fa_size - offset;
}

rc = flash_area_flatten(ctx->flash_area, offset, size);
}
#endif

return rc;
}


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

rc = stream_flash_buffered_write(&ctx->stream, data, len, flush);
if (!flush) {
/* If there is a need to erase the trailer, that should happen before any
* write is done to partition.
*/
rc = scramble_mcuboot_trailer(ctx);
if (rc != 0) {
return rc;
}

#ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
ssize_t status_offset = boot_get_trailer_status_offset(
ctx->flash_area->fa_size);

#ifdef CONFIG_STREAM_FLASH_ERASE
const struct flash_parameters *fparams =
flash_get_parameters(flash_area_get_device(ctx->flash_area));

if ((flash_params_get_erase_cap(fparams) & FLASH_ERASE_C_EXPLICIT)) {
/* use pistine-page-erase procedure for a device which needs it */
rc = stream_flash_erase_page(&ctx->stream,
ctx->flash_area->fa_off +
status_offset);
} else
#endif
{
if (status_offset > stream_flash_bytes_written(&ctx->stream)) {
rc = flash_area_flatten(ctx->flash_area, status_offset,
ctx->flash_area->fa_off - status_offset);
} else {
rc = 0;
}
}

if (rc) {
/* if CONFIG_IMG_ERASE_PROGRESSIVELY is enabled the enabled CONFIG_STREAM_FLASH_ERASE
* ensures that stream_flash erases flash progresively.
*/
rc = stream_flash_buffered_write(&ctx->stream, data, len, flush);
if (!flush) {
return rc;
}
#endif

flash_area_close(ctx->flash_area);
ctx->flash_area = NULL;
Expand Down

0 comments on commit a0a34c2

Please sign in to comment.