Skip to content

Commit 30ff6f6

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 b9251e2 commit 30ff6f6

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
@@ -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: 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)