Skip to content

Commit f6182f1

Browse files
committed
[nrf fromlist] susbys/dfu/img_util: refined ERASE PROGRESSIVELY implementation
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]>
1 parent ae75e9e commit f6182f1

File tree

2 files changed

+59
-29
lines changed

2 files changed

+59
-29
lines changed

subsys/dfu/Kconfig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ config IMG_BLOCK_BUF_SIZE
6868

6969
config IMG_ERASE_PROGRESSIVELY
7070
bool "Erase flash progressively when receiving new firmware"
71-
select STREAM_FLASH_ERASE
72-
depends on FLASH_HAS_EXPLICIT_ERASE
71+
select STREAM_FLASH_ERASE if FLASH_HAS_EXPLICIT_ERASE
7372
help
7473
If enabled, flash is erased as necessary when receiving new firmware,
7574
instead of erasing the whole image slot at once. This is necessary

subsys/dfu/img_util/flash_img.c

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -43,44 +43,75 @@ BUILD_ASSERT((CONFIG_IMG_BLOCK_BUF_SIZE % FLASH_WRITE_BLOCK_SIZE == 0),
4343
"FLASH_WRITE_BLOCK_SIZE");
4444
#endif
4545

46+
static int scramble_mcuboot_trailer(struct flash_img_context *ctx)
47+
{
48+
int rc = 0;
49+
50+
#ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
51+
if (stream_flash_bytes_written(&ctx->stream) == 0) {
52+
off_t toff = boot_get_trailer_status_offset(ctx->flash_area->fa_size);
53+
off_t offset;
54+
size_t size;
55+
const struct flash_parameters *fparams =
56+
flash_get_parameters(flash_area_get_device(ctx->flash_area));
57+
#ifdef CONFIG_STREAM_FLASH_ERASE
58+
/* for erasable devices prgressive-erase works only along with
59+
* CONFIG_STREAM_FLASH_ERASE option*/
60+
if (flash_params_get_erase_cap(fparams) & FLASH_ERASE_C_EXPLICIT) {
61+
/* On devices with explicit erase we are aligning to page
62+
* layout.
63+
*/
64+
struct flash_pages_info info;
65+
66+
rc = flash_get_page_info_by_offs(flash_area_get_device(ctx->flash_area),
67+
if (rc != 0) {
68+
return rc;
69+
}
70+
offset = info.start_offset;
71+
size = info.size;
72+
73+
} else
74+
#endif
75+
{
76+
77+
/* On devices with no erase, we are aligning to write block
78+
* size.
79+
*/
80+
offset = (toff + fparams->write_block_size - 1) &
81+
~(fparams->write_block_size - 1);
82+
/* No alignment correction neede here, offset is corrected already */
83+
size = ctx->flash_area->fa_size - offset;
84+
}
85+
86+
rc = flash_area_flatten(ctx->flash_area, offset, size);
87+
}
88+
#endif
89+
90+
return rc;
91+
}
92+
93+
4694
int flash_img_buffered_write(struct flash_img_context *ctx, const uint8_t *data,
4795
size_t len, bool flush)
4896
{
4997
int rc;
5098

51-
rc = stream_flash_buffered_write(&ctx->stream, data, len, flush);
52-
if (!flush) {
99+
/* If there is need to erase trailer, that should happen before any
100+
* write is done to partition.
101+
*/
102+
rc = scramble_mcuboot_trailer(ctx);
103+
if (rc != 0) {
53104
return rc;
54105
}
55106

56-
#ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
57-
ssize_t status_offset = boot_get_trailer_status_offset(
58-
ctx->flash_area->fa_size);
59107

60-
#ifdef CONFIG_STREAM_FLASH_ERASE
61-
const struct flash_parameters *fparams =
62-
flash_get_parameters(flash_area_get_device(ctx->flash_area));
63-
64-
if ((flash_params_get_erase_cap(fparams) & FLASH_ERASE_C_EXPLICIT)) {
65-
/* use pistine-page-erase procedure for a device which needs it */
66-
rc = stream_flash_erase_page(&ctx->stream,
67-
ctx->flash_area->fa_off +
68-
status_offset);
69-
} else
70-
#endif
71-
{
72-
if (status_offset > stream_flash_bytes_written(&ctx->stream)) {
73-
rc = flash_area_flatten(ctx->flash_area, status_offset,
74-
ctx->flash_area->fa_off - status_offset);
75-
} else {
76-
rc = 0;
77-
}
78-
}
79-
80-
if (rc) {
108+
/* if CONFIG_IMG_ERASE_PROGRESSIVELY is enabled the enabled CONFIG_STREAM_FLASH_ERASE
109+
* ensures that stream_flash erases flash progresively.
110+
*/
111+
rc = stream_flash_buffered_write(&ctx->stream, data, len, flush);
112+
if (!flush) {
81113
return rc;
82114
}
83-
#endif
84115

85116
flash_area_close(ctx->flash_area);
86117
ctx->flash_area = NULL;

0 commit comments

Comments
 (0)