Skip to content

Commit 17c15e3

Browse files
nvlsianpunashif
authored andcommitted
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. Signed-off-by: Andrzej Puzdrowski <[email protected]>
1 parent 3013604 commit 17c15e3

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

subsys/dfu/Kconfig

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

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

subsys/dfu/img_util/flash_img.c

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,78 @@ 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+
*/
61+
if (flash_params_get_erase_cap(fparams) & FLASH_ERASE_C_EXPLICIT) {
62+
/* On devices with explicit erase we are aligning to page
63+
* layout.
64+
*/
65+
struct flash_pages_info info;
66+
67+
rc = flash_get_page_info_by_offs(flash_area_get_device(ctx->flash_area),
68+
toff, &info);
69+
if (rc != 0) {
70+
return rc;
71+
}
72+
offset = info.start_offset;
73+
size = info.size;
74+
75+
} else
76+
#endif
77+
{
78+
/* On devices with no erase, we are aligning to write block
79+
* size.
80+
*/
81+
offset = (toff + fparams->write_block_size - 1) &
82+
~(fparams->write_block_size - 1);
83+
/* No alignment correction needed here, offset is corrected already
84+
* and, size should be aligned.
85+
*/
86+
size = ctx->flash_area->fa_size - offset;
87+
}
88+
89+
rc = flash_area_flatten(ctx->flash_area, offset, size);
90+
}
91+
#endif
92+
93+
return rc;
94+
}
95+
96+
4697
int flash_img_buffered_write(struct flash_img_context *ctx, const uint8_t *data,
4798
size_t len, bool flush)
4899
{
49100
int rc;
50101

51-
rc = stream_flash_buffered_write(&ctx->stream, data, len, flush);
52-
if (!flush) {
102+
/* If there is a need to erase the trailer, that should happen before any
103+
* write is done to partition.
104+
*/
105+
rc = scramble_mcuboot_trailer(ctx);
106+
if (rc != 0) {
53107
return rc;
54108
}
55109

56-
#ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
57-
ssize_t status_offset = boot_get_trailer_status_offset(
58-
ctx->flash_area->fa_size);
59-
rc = stream_flash_erase_page(&ctx->stream,
60-
ctx->flash_area->fa_off +
61-
status_offset);
62-
if (rc) {
110+
111+
/* if CONFIG_IMG_ERASE_PROGRESSIVELY is enabled the enabled CONFIG_STREAM_FLASH_ERASE
112+
* ensures that stream_flash erases flash progresively.
113+
*/
114+
rc = stream_flash_buffered_write(&ctx->stream, data, len, flush);
115+
if (!flush) {
63116
return rc;
64117
}
65-
#endif
66118

67119
flash_area_close(ctx->flash_area);
68120
ctx->flash_area = NULL;

0 commit comments

Comments
 (0)