On some devices, the flash memory will allow you to 'write' multiple times to the same page as long as you're writing all 1s (or in some devices it will always allow you to overwrite - with the caveat that you are aware that you can only clear bits and not set them).
This small change will allow for cleaner APIs to be built on top of the EFL, which need to do multiple read-modify-writes on embedded flash while minimizing the number of erase cycles required. Without this, when doing multiple read-modify-write operations you would have to:
1. Erase the entire sector before each RMW operation.
2. Erase the sector once, but keep track of which pages contain all 1s when writing - this results in more overhead to inspect memory and calls to EFL API.
3. Other shenanigans I haven't thought of.
Code: Select all
diff --git c/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c w/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
index 6ea46f8b1..009336c74 100644
--- c/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
+++ w/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
@@ -313,6 +313,15 @@ flash_error_t efl_lld_program(void *instance, flash_offset_t offset,
}
while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
+ if (efl_lld_descriptor.attributes & FLASH_ATTR_ERASED_IS_ONE)
+ {
+ /* Don't program page if data is all 1s */
+ if ((line.w[0] == 0xFFFFFFFF) && (line.w[1] == 0xFFFFFFFF))
+ {
+ continue;
+ }
+ }
+
/* Programming line.*/
address[0] = line.w[0];
address[1] = line.w[1];