EEPROM Broken on 0.4.9?

I think there may be something broken with EEPROM in 0.4.9. I have code that saves some calibration data that’s stopped working with the upgrade. I’ve reduced my code to a fairly minimal set of functionality that fails to work. I’ve tried all the various read/write functions. They all seem to fail. See below…

Am I missing something, or is EEPROM read/write broken? Anyone else seeing issues on 0.4.9? I believe this is covered in another issue opened recently, but retained variables also seem to be lost when waking from a deep sleep in the latest build.

Here’s the minimal code that fails to run on 0.4.9:

#include "application.h"
//SYSTEM_MODE(MANUAL);

uint8_t number;

int resetCount(String args) {
	number = 0;
	EEPROM.update(0, number);
	return 1;
}

void setup() {
	Serial.begin(9600);
	Particle.function("reset", resetCount);
}

void loop() {

//	number = EEPROM.read(0);
	EEPROM.get(0,number);
	
	Serial.print("Number ");
	Serial.println(number);

	EEPROM.update(0, number + 1);
//	EEPROM.put(0,number + 1);
//	EEPROM.write(0, number + 1);

	delay(1000);
}

I modified the code slightly to also test retained variables and deep sleep.

Test procedure:

  • flash the code to the device
  • connect to serial and press a key
  • make note of the two numbers printed
  • the device will sleep, when it awakes,
  • connect to serial and press a key
  • make note of the two numbers printed,
  • verify they are each 1 more than the previous value (if the number was previously 255 it will reset to 0.)
  • calling the “reset” cloud function resets the first number but not the second. To reset the 2nd number, power down the device for 30 seconds.

I tested by flashing the app from the compile farm and updating to 0.4.9 using particle update.

#include "application.h"
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
uint8_t number;
retained uint8_t number2;

int resetCount(String args) {
        number = 0;
        EEPROM.update(0, number);
        return 1;
}

void setup() {
        Serial.begin(9600);
        Particle.function("reset", resetCount);
}

void loop() {
        EEPROM.get(0,number);
        while (!Serial.available()) Particle.process();

        Serial.print("Number ");
        Serial.println(number);
        Serial.println(number2++);        
        EEPROM.update(0, number + 1);

        delay(1000);
        System.sleep(SLEEP_MODE_DEEP, 5);
}
1 Like

Thanks mdma.

After your note, I fired up your code on my chip at home and it worked fine, but when I came back to the office this morning to try it on the chip that was causing me trouble, it still wasn’t working.

Both my code and your code work fine on one unit and not on another. Both are reporting firmware version 0.4.9… Does that mean it’s likely to be a physical problem? Are there different layers of software/firmware that may be to blame? Any deeper registry settings that might have gotten out of whack?

You could try erasing the EEPROM - it may have become corrupted.

First, we’ll take a copy of the eeprom for later analysis. Put the device in DFU mode and run:

dfu-util -d 2b04:d006 -a 0 -s 0x800C000:0x14000 -U quirky_eeprom.bin

Then in an application sketch you can erase the eeprom sectors like this:

bool FLASH_EraseMemory(flash_device_t flashDeviceID, uint32_t startAddress, uint32_t length);

int eraseEeprom(String arg)
{
	bool result = FLASH_EraseMemory(FLASH_INTERNAL, 0x800C000, 0x14000);
	if (result) {
	Serial.println("Erased flash memory. Please restart the device. Restarting...");
	delay(1000);
	System.reset();}
	else { Serial.println("Flash erase failed.");}
	return 0;
}

void setup()
{
    Particle.function("erase", eraseEeprom);
}

Try that please, let me know how it goes!

1 Like

The erase function seemed to do the trick. Works just fine now. Thanks.

Does it wear on the memory to erase the flash that way? I’m wondering about having a periodic erase built into the code for when it’s out in the field if I can’t figure out why this happened.

bin from the device before the erase is here:
https://drive.google.com/folderview?id=0B-M_ppVvxXTYbUFkVGNQaDRaQk0&usp=sharing

As I was shifting back to my real code, I noticed a path that could result in a write to EEPROM followed immediately by a deep sleep. If it’s possible that the write would have been occurring while going to sleep, perhaps this could have caused the corruption?

@KevinW I’m working on a big rework of the EEPROM code to eliminate all possibilities of bad writes, especially failing to recover when there is bad data. It will also ensure block writes (writing a double or an entire struct) are consistent so you never have partial old data and partial new data.

Your EEPROM dump definitely has some bad data in it (I’m not sure why though). I’ll run it through my new algorithm to make sure it recovers properly. Thanks for sharing!

4 Likes

Yes, it counts as a single erase. The internal flash is good for at least 10,000 erases.