2020-08-11 01:11 AM
Hi Community,
I am using the EEPROM emulation library from ST (X-CUBE-EEPROM_V2.0.0) in a project with the STM32G070, and I am trying to understand why should I use EE_FORCED_ERASE in EE_Init function
I found this in the documentation (AN4894) :
EE_Init
Configures the EEPROM emulation variables to their initial state and restores
the Flash pages to a known good state in case of asynchronous reset or
power loss during Flash write or erase operation.
Erases the Flash pages that need to be erased (for instance pages not fully
erased in ERASE state, pages in ERASING state). The EE_FORCE_ERASE
parameter has to be used by default. If the application guarantees that no
asynchronous reset nor power loss can happen during Flash write or erase
operations, then the EE_CONDITIONAL_ERASE parameter can be used; refer
to Section 4.6.2: Page header recovery.
After reset, this function should be systematically called prior to accessing the
emulated EEPROM.
4.6.2 Page header recovery
.... In order to avoid a possible failure scenario, erased pages are systematically erased again
upon reset (in the EE_Init routine). This ensures a safe behavior but consumes cycling
capability of the emulated EEPROM. This systematic erase can be avoided if the application
is designed not to generate an asynchronous reset or power failure during Flash writes or
erases. Refer to Section 6.2: Detecting power failures for more details.
6.2 Detecting power failures
If no asynchronous reset can be generated by the application, the only way to corrupt the
Flash programming or erasing operations is the case of power failure. The application can
use the PVD in order to not generate a Flash write or erase operation during the VDD ramp
down. An example of this PVD (Programmable Voltage Detector) usage is provided in the
EEPROM example main application.
The decoupling capacitors or battery must be sized to provide enough power to the chip
during the full write or erase operation and before the supply voltage goes below 1.7 V
(minimal operating voltage) or before a BOR (Brown Out Reset) is generated. In this case,
the EE_CONDITIONAL_ERASE parameter of the EE_Init routine can be used. In all other
cases, the EE_FORCE_ERASE parameter has to be used.
And looking into the code I spotted this inside the EE_init (the only code that checks the EraseType parameter):
/* Check if page erase has to be forced unconditionally (default case) */
if (EraseType == EE_FORCED_ERASE)
{
/* Force page erase independently of its content */
if (FI_PageErase(page, 1U) != EE_OK)
{
return EE_ERASE_ERROR;
}
}
else /* EraseType == EE_CONDITIONAL_ERASE */
{
/* Check if page is fully erased */
if (VerifyPageFullyErased(pageaddress, PAGE_SIZE) == EE_PAGE_NOTERASED)
{
/* Erase pages if not fully erased */
if (FI_PageErase(page, 1U) != EE_OK)
{
return EE_ERASE_ERROR;
}
}
}
Where the VerifyPageFullyErased function does exact what it says:
static EE_Status VerifyPageFullyErased(uint32_t Address, uint32_t PageSize)
{
EE_Status readstatus = EE_PAGE_ERASED;
uint32_t counter = 0U;
/* Check each element in the page */
while (counter < PageSize)
{
/* Compare the read address with the virtual address */
if ((*(__IO EE_ELEMENT_TYPE*)(Address+counter)) != EE_PAGESTAT_ERASED)
{
/* In case one element is not erased, reset readstatus flag */
readstatus = EE_PAGE_NOTERASED;
}
/* Next address location */
counter = counter + EE_ELEMENT_SIZE;
}
/* Return readstatus value */
return readstatus;
}
Question 1:
So, in my actual scenario I can't ensure that no reset will occur during a write or erase, so I must use the FORCED_ERASE parameter.. but why exactly?
The documentation states that it is because of flash corruption during erase, but from what I understood in the code above, the erased page will be checked anyway, and a full erase will be triggered if any word in a page is not erased.. so it will be erased in case of corruption during erase anyway, not?
Avoiding unnecessary flash erasing is mandatory in my application, as the G070 line only withstands 1k erase cycles instead of the traditional 10k cycles from other families (and G071).. so erasing blank pages at every boot is not an option for me...
Another solution would be detecting the ramp down in the VCC line, but since the G070 does not have PVD I'll need to do this myself using an external "Under Voltage Detector" IC, or even the analog watchdog together with the internal voltage reference (this one could be more tricky as it depends on the ADC sampling for detection, and my actual ADC sampling frequency is pretty low), and of course put enough capacitance in the VCC line ...
Question 2: Has anyone already implemented any of this solutions for detecting VDD ramp down in a uC with no PVD and could share some knowledge?
2020-08-11 04:58 AM
There is likely a state where the page can be actively erasing, but your code may not be aware due to an unexpected reset event. I could see this happening.
It's also possible to write your own EEProm that can save multiple versions of data and only erases the page when it runs out of space. If the data you're saving is very small in comparison to the page size, this can alleviate the issue of the flash wearing out. You'd have to implement your own solution for this.
2020-08-11 09:57 AM
The EEPROM emulation library can not recover from an interrupted write or erase operation. If your application doesn't tolerate this, it is better to use a completely fail safe library like Littlefs or SPIFFS.