In SDK v3.2.0, EEPROM.begin() sometimes fails after a reboot(need to call EEPROM.begin() again). This issue doesn't occur in SDK v1.0.6 #11454
-
BoardESP32 Device DescriptionESP32 Devkit Hardware ConfigurationNo Hardware Configuration, only reading Internal Flash EEPROM. Versionv3.2.0 IDE NameArduino IDE Operating SystemWindows 11 Flash frequency80MHz PSRAM enabledno Upload speed921600 DescriptionIn SDK version v3.2.0, the EEPROM.begin() function intermittently fails when called after a device reboot. This behavior does not occur in SDK v1.0.6, where EEPROM.begin() works reliably under the same conditions. Sketch#include <EEPROM.h>
#define EEPROM_SIZE 4000
void setup() {
Serial.begin(115200);
if (!EEPROM.begin(EEPROM_SIZE)) {
Serial.println("EEPROM.begin() FAILED!");
} else {
Serial.println("EEPROM.begin() succeeded.");
}
}
void loop() {
ESP.restart(); // Reboot the device to observe if EEPROM.begin fails after reboot
} Debug Message
Other Steps to ReproduceRun This is both SDK 3.2.0, and SDK 1.6.0 I have checked existing issues, online documentation and the Troubleshooting Guide
|
Beta Was this translation helpful? Give feedback.
Replies: 12 comments 1 reply
-
Please set core debug level to verbose and flash the firmware again. Post the detailed log. This should show the reason for the failure. |
Beta Was this translation helpful? Give feedback.
-
I can't reproduce it. I have run it over 10,000 times with no failure - using Arduino Core 3.2.0 and ESP32 Dev kit. In order to test this issue, I have modified the sketch to show me how many time it has restated, if it has failed (including an LED to show me the status). You can try it as well... #include <EEPROM.h>
#define EEPROM_SIZE 4000
#define LED_PIN 21
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int failureCount = 0;
RTC_DATA_ATTR bool EEPROM_HasFailed = false;
void setup() {
Serial.begin(115200);
// just runs in the first time it boots to test the LED
if (bootCount == 0) {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
}
//Increment boot number and print it every reboot
++bootCount;
Serial.println("Boot number: " + String(bootCount) + " || #Failures = " + String(failureCount));
if (!EEPROM.begin(EEPROM_SIZE)) {
Serial.println("EEPROM.begin()============================>>>>>>>> FAILED!");
EEPROM_HasFailed = true;
failureCount++;
} else {
Serial.println("EEPROM.begin() succeeded.");
delay(150); // just to be able to glance it in the Serial Monitor
}
// shows the failure
if (EEPROM_HasFailed) {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
delay(5000);
}
esp_sleep_enable_timer_wakeup(10);
esp_deep_sleep_start();
//ESP.restart(); // Reboot the device to observe if EEPROM.begin fails after reboot
}
void loop() {
} |
Beta Was this translation helpful? Give feedback.
-
We encountered another EEPROM-related issue: Its very rare to generate issue, From 100 of devices, we get issue in 3 device. |
Beta Was this translation helpful? Give feedback.
-
So this 3 devices are faulty. |
Beta Was this translation helpful? Give feedback.
-
EEPROM Library simulates EEPROM functionality over regular Flash space for storing data. Please note that EEPROM Arduino Library is deprecated as stated here: https://github.com/espressif/arduino-esp32/tree/master/libraries/EEPROM
There are other libraries that may help better with the wear out issue, such as LittleFS or FatFS. Dynamic wear leveling - littlefs is designed with flash in mind, and provides wear leveling over dynamic blocks. Additionally, littlefs can detect bad blocks and work around them. Bounded RAM/ROM - littlefs is designed to work with a small amount of memory. ESP IDF also has support to Wear Leveling: |
Beta Was this translation helpful? Give feedback.
-
NVS also has wear leveling. But, the default size is only 20k, so there's only 5 sectors to level across. If you are using the flash heavily for NVS (which is not a great design to start with), it would make sense to allocate more space to provide for a longer lifetime of the device. |
Beta Was this translation helpful? Give feedback.
-
@lbernstone Thanks for pointing to Configuration data is stored in flash using the EEPROM library. It is read either during reboot or when a configuration update occurs (typically 2 to 5 times at most). For all other operations, the configuration is maintained in a global structure variable in RAM. The size of this configuration structure is approximately 225 bytes. The ESP32 is currently operating on a single core. The main logic runs in the loop() function, and any additional tasks—such as LED handling—are also executed on the same core. However, we are observing a critical issue: after reading configuration data from flash into the structure, the data appears to get altered and auto-corrected unexpectedly during runtime. This is concerning and could potentially indicate memory corruption or environmental interference.
Questions:
|
Beta Was this translation helpful? Give feedback.
-
This forum is for code in this repo. You are now way off topic. |
Beta Was this translation helpful? Give feedback.
-
@lbernstone Apologies if I seemed off-topic earlier. What I intended to ask was more about the code-level handling for such situations. Specifically, how can we detect if memory has been corrupted, so that we can take appropriate action in response? While we can try to mitigate electrical noise through hardware measures, I believe that alone may not be a complete solution. It would be more robust if we also implement software-side safeguards to ensure data integrity and reliability. |
Beta Was this translation helpful? Give feedback.
-
it may be possible to store a binary blob that included some CRC for data integrity verification... This would be a change in the way how data is stored in the NVS. Instead of storing data fields, one by one, it could create a data structure that includes a CRC or something similar as a binary blob into the NVS. |
Beta Was this translation helpful? Give feedback.
-
You could also use the last 4 or 8 bytes of your EEPROM to store a checksum of the rest of the content and verify on every read. That would be a pretty easy mod to the library. If you want to go full NASA, then make another nvs partition on the flash, and double-write everything (in addition to the checksum). |
Beta Was this translation helpful? Give feedback.
-
Thank you for the suggestion to use CRC during EEPROM read/write operations — that will definitely help in detecting issues related to EEPROM data integrity. However, we’re also facing a different issue related to RAM corruption, and I’d appreciate your input on how to handle it.
How can we detect and handle such a case where a global RAM variable gets corrupted and then seemingly recovers, even though we don’t explicitly touch it? |
Beta Was this translation helpful? Give feedback.
it may be possible to store a binary blob that included some CRC for data integrity verification... This would be a change in the way how data is stored in the NVS. Instead of storing data fields, one by one, it could create a data structure that includes a CRC or something similar as a binary blob into the NVS.