EFL driver: don't write FFs
Posted: Thu Dec 23, 2021 10:10 pm
STM32 EFL drivers shouldn't to write to flash if the entire page the user wants to write contain 1s. On the STM32, if you write to a page - even if it is all 1s and did not change the state of flash, it generates a page write error on a subsequent write.
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.
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];