Skip to content

Conversation

rondlh
Copy link

@rondlh rondlh commented Oct 2, 2025

This PR implements a simple flash wear leveling on various hardware.

Flash wear leveling

User settings are stored in the MCU onboard flash memory (except for the MKS TFT35 V1.0 which uses an AT24C16 EEPROM).
The STM datasheet guarantees 10K writes. The onboard SPI flash guarantees 100K writes, and the AT24C16 guarantees 1 million writes. So the SPI flash seems to be a good candidate to hold user settings, but the onboard program memory was selected.
For example, the BTT TFT35 V3.0 uses a 16K flash sector to hold less than 256 bytes of data. The whole sector is erased every time a user parameter is changed. This not only takes time, but also wears out the flash memory. The implemented wear leveling algorithm improves the wear leveling by a factor of 64, allowing 640K writes. Also responsiveness is improved as interrupt are disabled during flash erase cycles.
For other hardware like the BTT TFT35 V3.0.1 the benefit is less, but still an improvement of a factor of 8 is achieved, the improvement is less because the used flash sector is only 2KB, this could be increased if required.
Part of the improvement is achieve by not writing more data than needed. The settings are less than 256 bytes, but still always 384 bytes were written to flash. The unused data values are usually 0, which is the worst case scenario for flash memory. It would be better to initialize the data record to the status of erased flash (0xFF) so the cells that do not need to change are not changed.

FlashStore cleanup

The flash store did some odd things which were improved.

  1. It skipped the first 32 bit word of the record it reads and writes.
  2. It changes the endianness of some data, like the signatures, which is not needed and actually makes the data harder to find (when using CubeProgrammer etc.). When loading back the data the endianness is changed back again. The additional code to handle this is not needed.
  3. Generally the code was difficult to read:
wordToByte(PARA_SIGN, data + (index += 4));
memcpy(data + (index += 4), &infoSettings, sizeof(SETTINGS));

  1. A 16 bit CRC was used to check if the old and new data are different and thus saving is required. This allows for odd cases were data cannot be saved just because by accident the CRC value is the same (1 in 65K cases). This has been improved by using a 32bit CRC value.
  2. An assert was added to make sure the user settings fit into the reserved area, currently 12 bytes are still available for more user settings.

Requirements

Any TFT, except MKS TFT35 V1.0

Benefits

Flash wear leveling
More responsive saving of user settings
Some flash store code cleanup and assert
More reliable flash storage handling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant