Fix EEPROM Emulation caching issue on Cortex-M4#186
Conversation
|
Hm interesting theory. But to my knowledge this issue only happens in new chips from specific factories and never occurs again after a few erase cycles indicating to me that it may have something to do with the physical flash itself possibly not erasing/initializing properly. If it was just the cache i would expect it to happen randomly instead. But it shouldn't hurt to invalidate the cache for writing if it is a cache critical operation then. |
6577014 to
3eb87fb
Compare
| __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR); | ||
| __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGPERR); | ||
| __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR); | ||
| Flash_InvalidateDataCache(); // Invalidate before writing because EE_ReadVariable just cached the flash page |
There was a problem hiding this comment.
Maybe instead of invalidating both before and after the write only disable before writing and reset and reenable after writing. Or does it make sense to keep the cache active during the access?
The most likely cause is probably the init section if it occurs with fresh chips that have not been erased properly yet.
3eb87fb to
6577014
Compare
6577014 to
d0a8639
Compare
|
Thanks! I have rebased the PR on master and removed the unrelated changes as requested. The commit message was also updated to provide a more detailed technical explanation of the issue. |
Description of the Issue:
Users compiling with newer toolchains (e.g. GCC 13/15) or running on certain STM32F407 hardware were experiencing an issue where saving configurations failed silently. The Configurator/UI reported "Save in flash: OK", but after a reboot, the settings reverted to their defaults.
Root Cause:
The STMicroelectronics EEPROM Emulation library (
eeprom.c) uses consecutive flash reads duringEE_VerifyPageFullWriteVariableto find an empty slot (0xFFFFFFFF) in the active flash page.However, on processors with an ART Data Cache (like Cortex-M4/M7), these reads can get cached. If the flash sector was recently erased (or formatted), the memory reads inside the
EE_ReadVariableloop result in the CPU aggressively caching empty or stale data values.When
EE_VerifyPageFullWriteVariableattempts to write later, the cached (stale) data is read back instead of the actual physical flash data. Because it doesn't see0xFFFFFFFF, the library incorrectly assumes the page is completely full (PAGE_FULLerror). The write is silently skipped and dropped.The Solution:
To resolve this desynchronization between the physical flash and the CPU Data Cache during In-Application Programming (IAP), we explicitly flush/invalidate the data cache right before calling
EE_WriteVariable().Flash_InvalidateDataCache()now correctly wraps the write operation (before and after).Safety and Regressions:
__HAL_FLASH_DATA_CACHE_DISABLEmacro is naturally undefined by the ST HAL, so the cache clearing function compiles to an empty, harmless operation.Flash_InvalidateDataCache()immediately after the write operation; adding it before simply guarantees a clean slate for the pre-write reads.