Skip to content

EEPROM crashes #240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
holgerlembke opened this issue May 14, 2015 · 15 comments
Closed

EEPROM crashes #240

holgerlembke opened this issue May 14, 2015 · 15 comments

Comments

@holgerlembke
Copy link
Contributor

this small thing crashes my ESP8266-12 every time it runs. Results in reboot.

include <EEPROM.h>

void eepromtest(void) {
EEPROM.begin(512);

for (int i=0;i<10;i++) {
EEPROM.write(random(0,500),random(0,255));
}

EEPROM.end();
}

void setup() {
for (int i=0;i=100;i++) {
eepromtest();

}
}

void loop() {
delay(1000);
}

@holgerlembke
Copy link
Contributor Author

Remark: at some times in some stages I write config data to EEPROM. That is not done often, just the other day or so.

And my program crashes after that. I spend a day debugging my source... Then I came up with this.

@sticilface
Copy link
Contributor

Looks like you are calling EEPROM.begin(512);

with every loop of your for.... try this instead.... and remove EEPROM.begin(512) from eepromtest...

void setup() {
EEPROM.begin(512);
for (int i=0;i=100;i++) {
eepromtest();
}

@holgerlembke
Copy link
Contributor Author

I would, but that is not the way I think it should work. I want to be "reboot save" with my data, so every time I change config I want to write it back.

I changed it to this:

#include <EEPROM.h>

void eepromtest(void) {

for (int i=0;i<10;i++) {
EEPROM.write(random(0,500),random(0,255));
}

EEPROM.commit();
}

void setup() {
EEPROM.begin(512);

for (int i=0;i=100;i++) {
eepromtest();

}
}

void loop() {
delay(1000);
}

Reboots, too.

@marvinroger
Copy link
Contributor

I don't know if that might help, but I had similar problems while reading TOUT pin a lot of consecutive times. Try adding a yield() to the eepromtest(). Don't know why, but that solved it for me.

@holgerlembke
Copy link
Contributor Author

Ok, apparently, marvinroger woke me up. I remember the problem with background tasks and watchdog timer and noticed that the reset showed a wdt-reboot. So.... attached is a working solution.

Notice the remarks at the end. My program runs for about 4748 milliseconds. This is for about 100 loops, so 470 ms per loop. So begin/end seems to need about 500ms. This might explain why it raises my watchdog timer...

I would suggest someone with more hardware knowledge writes a small chapter about how that wdt works, if it is needed, how to avoid such situation and such...

And perhaps a yield() added to the eeprom routines? I'm not sure if this is the right strategy...

Any comments? Thanks!

#include <EEPROM.h>

void eepromtest(void) {
EEPROM.begin(5120);

EEPROM.write(5,7);

EEPROM.end();
yield();
}

void setup() {
Serial.begin(115200);
delay(5000);
Serial.println("Start");

unsigned long start = millis();
for (int i=0;i<100;i++) {
eepromtest();
}

Serial.println(millis()-start);

Serial.println("done");
}

void loop() {
delay(1000);
}

// Start
// 4748
// done

@holgerlembke
Copy link
Contributor Author

It is unsatisfying. It crashes more or less randomly:

ets Jan 8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x40100000, len 28896, room 16
tail 0
chksum 0x0d
load 0x3ffe8000, len 1564, room 8
tail 4
chksum 0x91
load 0x3ffe8620, len 4720, room 4
tail 12
chksum 0xa5
csum 0xa5

I added yield(); in front and after all the suspiciouse routines in EEPROM.cpp, it is a little bit better, but still after .end it chrashes... And it can't work, because it does not change the state of the watchdog timer. Or does it? No, it doesn't. So I changed it to ESP.wdtFeed(); which seems to help a lot. I fear that the watchdog could become some sort of trouble for beginners...

@Makuna
Copy link
Collaborator

Makuna commented May 15, 2015

I really don't understand your sample. Why are you calling EEPROM.begin() more than once?

Pull the begin() and end() out of your loop. Just call write() and then call commit() inside the loop.

@holgerlembke
Copy link
Contributor Author

Makuna,

reason is simple:

  • RAM is an expensive resource. A EEPROM.begin(512) uses at least 512 Bytes of RAM.
  • Updates into EEPROM are "user driven". User changes something, I need to write it into EEPROM. User might never change something or three times a day. Who knows...

So the idea is only to access the EEPROM if it is really needed and after that free the resources.

The above program was only to experiment and see/verify/research the problem.

@Makuna
Copy link
Collaborator

Makuna commented May 15, 2015

Good point, seems like it should not cache very much as you are used to slow eeprom access, wonder why it allocates a cache?

@sticilface
Copy link
Contributor

In your last sketch you call EEPROM.begin(5120).

from the docs...

Size can be anywhere between 4 and 4096 bytes

Possible cause?

@holgerlembke
Copy link
Contributor Author

No, copy and paste typo.

@holgerlembke
Copy link
Contributor Author

Makuna,

because there is no EEPROM.

Instead they use a part of FLASH. And to avoid reprogramming the FLASH with every byte (which, if I recall correctly. ends with some chunks of memory been written anyway) write there is the cache.

At least this is what I read from the EEPROM.cpp file.

@holgerlembke
Copy link
Contributor Author

I gave up on my EEPROM--wdt-reboot.. It just still happens and I don't know why. Program runs happily all day long, until I touch anything within the EEPROM.end() or .commit().

So I added "wdtFeed", get less wdt-reboots.

Just some minutes ago I was in my rabbit hole again: two .commit(), wdt-reboot after second.

Now I changed it to .wdtDisable() and .wdtEnable(WDTO_0MS); around the .begin() and .commit(). No reboots so far.

@sticilface
Copy link
Contributor

I'm thinking there may be some bugs with the boards manager / spiffs version and EEPROM too.... I get a lot of reboots, not entirely sure its down to this. But now the EEPROM-clear sketch does NOT clear the EEPROM. so something is not working quite right.

@sticilface
Copy link
Contributor

Fixed

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

No branches or pull requests

4 participants