From 3f0b5d3fd1307bc64c67fee73cda9e6ef5c21d61 Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 2 Jan 2025 13:31:21 +0100 Subject: [PATCH 1/2] Fix flash wear leveling sector calculation --- .../chibios/drivers/wear_leveling/wear_leveling_efl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c index fed16d20b1a..1a331e1a474 100644 --- a/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c +++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c @@ -84,12 +84,14 @@ bool backing_store_init(void) { // Work out how many sectors we want to use, working backwards from the end of the flash flash_sector_t last_sector = desc->sectors_count - WEAR_LEVELING_EFL_OMIT_LAST_SECTOR_COUNT; + + // skip sectors that are past the actual flash size + while (flashGetSectorOffset(flash, last_sector) >= flash_size) { + last_sector--; + } + for (flash_sector_t i = 0; i < last_sector; ++i) { first_sector = last_sector - i - 1; - if (flashGetSectorOffset(flash, first_sector) >= flash_size) { - last_sector = first_sector; - continue; - } counter += flashGetSectorSize(flash, first_sector); if (counter >= (WEAR_LEVELING_BACKING_SIZE)) { sector_count = last_sector - first_sector; From d0002d3f244488c4fe4fa834677a19d1ffb93347 Mon Sep 17 00:00:00 2001 From: Felix Date: Sat, 4 Jan 2025 12:24:56 +0100 Subject: [PATCH 2/2] Review changes * subtract WEAR_LEVELING_EFL_OMIT_LAST_SECTOR_COUNT after getting last_sector * don't pass value beyond desc->sectors_count to flashGetSectorOffset * add checks if not enough flash sectors are available --- .../drivers/wear_leveling/wear_leveling_efl.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c index 1a331e1a474..0df982b83ac 100644 --- a/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c +++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c @@ -83,13 +83,21 @@ bool backing_store_init(void) { #else // defined(WEAR_LEVELING_EFL_FIRST_SECTOR) // Work out how many sectors we want to use, working backwards from the end of the flash - flash_sector_t last_sector = desc->sectors_count - WEAR_LEVELING_EFL_OMIT_LAST_SECTOR_COUNT; + flash_sector_t last_sector = desc->sectors_count; // skip sectors that are past the actual flash size - while (flashGetSectorOffset(flash, last_sector) >= flash_size) { - last_sector--; + while (flashGetSectorOffset(flash, last_sector - 1) >= flash_size) { + if (--last_sector == 0) { + chSysHalt("No sector in available flash range"); + } } + if (WEAR_LEVELING_EFL_OMIT_LAST_SECTOR_COUNT >= last_sector) { + chSysHalt("Last sector intended to be used with wear_leveling is beyond available flash descriptor range"); + } + + last_sector -= WEAR_LEVELING_EFL_OMIT_LAST_SECTOR_COUNT; + for (flash_sector_t i = 0; i < last_sector; ++i) { first_sector = last_sector - i - 1; counter += flashGetSectorSize(flash, first_sector); @@ -100,6 +108,10 @@ bool backing_store_init(void) { } } + if (counter < WEAR_LEVELING_BACKING_SIZE) { + chSysHalt("Not enough flash is available for the requested wear_leveling size"); + } + #endif // defined(WEAR_LEVELING_EFL_FIRST_SECTOR) return true;