eeprom wear leveling question- some guidance please?
Rforbes
Posts: 281
Hiya folks,
I'm trying to understand eeproms a little better, and I'm not sure if my "wear leveling" routine will actually help. I'm a bit stumped on the intricacies of how the eeprom actually wears out over time with repeated writes.
I'm using a quickstart, and I have made the following method for writing data to the eeprom based on the day of the month (which I get from a spinneret, via ntp server(s))
My application uses this eeprom object: http://obex.parallax.com/object/23 by Kwabena W. Agyeman, created: 2013-03-28
I'm writing my data lots of times throughout the day- 1440 per day. So my goal is to minimize the # of writes to each chunk of eeprom to extend the life of it.
What I'm not getting is how page writes (I think that's the right term) work and how/if what I'm doing is helping me as I intend it to.
I've read somewhere that even if you only write 1 byte of data to some eeproms, it actually "writes" a whole page. So it's best to write in 1 page chunks at a time, or it's just wasted wear on the chip. Does this apply to all eeproms? Or am I off base here?
Thoughts? Advice?
Robert
I'm trying to understand eeproms a little better, and I'm not sure if my "wear leveling" routine will actually help. I'm a bit stumped on the intricacies of how the eeprom actually wears out over time with repeated writes.
I'm using a quickstart, and I have made the following method for writing data to the eeprom based on the day of the month (which I get from a spinneret, via ntp server(s))
My application uses this eeprom object: http://obex.parallax.com/object/23 by Kwabena W. Agyeman, created: 2013-03-28
OBJ eeprom : "I2C_ROMEngine" pub WriteEeprom|Address,i,temp,romaddress { Let's write our values to eeprom. We'll write 768 bytes for each Node Address into eeprom. The start location of the eeprom we'll write to is based on the day of the month. We'll write our bytes to 31 different locations throughout the month. When we need to read these values, we'll use the day of the month to tell us where to read from. EndAddress is a global variable. } romaddress:= $7D00 + (Day * 768) 'This starts our location at 768 bytes BEFORE $8000 repeat Address from 1 to EndAddress 'Write data for each of the Nodes. repeat i from 0 to 23 'Write data for each of the Nodes' data points temp:=Node[Address]._Value(i) eeprom.writelong(romaddress,temp) romaddress+=4 'dec 4 return 1
I'm writing my data lots of times throughout the day- 1440 per day. So my goal is to minimize the # of writes to each chunk of eeprom to extend the life of it.
What I'm not getting is how page writes (I think that's the right term) work and how/if what I'm doing is helping me as I intend it to.
I've read somewhere that even if you only write 1 byte of data to some eeproms, it actually "writes" a whole page. So it's best to write in 1 page chunks at a time, or it's just wasted wear on the chip. Does this apply to all eeproms? Or am I off base here?
Thoughts? Advice?
Robert
Comments
eg you might choose 10 or 100 rotating storage blocks, and each time you write, you erase the present one, and pgm the next.
Those blocks should be page-multiples.
That can be hard to nail down sometimes. Often EEPROM includes error correction as well, (not always clearly stated) to push up the usable cycles.
You are always better to erase as few times as possible, so if you can buffer data, do that.
Ok, I think I understand some of what you're saying. That's what I'm attempting to do, but I'm using 31 storage blocks. So, I have 31 "blocks" and on any given day, it's writing to a specific block based on the day. Since I'm writing to epprom in order to recover values after a power cycle, I can't really get away from writing so often (I guess I could, but I'd like to keep data recovery up to date within 1 minute.)
If you are open to alternatives: Consider SD instead of EEprom. SD so much cheaper per byte, and easier to replace.
If you can use forth, there is a logging pakage in propforth that provide microsecond time stamps, and can log once per second continuously no problem.
http://code.google.com/p/propforth/wiki/Logger1Simple
It does way more than you appear to need, but might be ultimately simpler to use.
You can read the log as its being written, so yo can off load the log to you PC without interupting the logging.
The biggest log tested so far was 110 meg after two weeks, and the SD has not failed yet even though the file head is being re-written once per second. To make down loading the logs easier, change the file so it creates a new log when the day rolls over. This should not ever fail, since any given file header would only be re-written for 24 hours. You can just save everything, forever (more or less), your data wouldn't fill a 2 gig card for years it seems.
If you can't use forth, the code might provide some ideas.
This needs a little care.
Certainly if a page does not change, skip of pgm saves cycles.
However, if the EE uses a hidden page design, (ie does a page read, updates one byte, then does erase/pgm ) then a design that skips bytes in a page, trying to save cycle lifetimes, can actually do the opposite.
EE Docs are vague on this stuff, and the Atmel data I looked does not even contain the word erase ?!
Another way to improve apparent cycles, is to store multiple blocks, using a coarse block designed to change (eg) hourly) and another (eg) Minutes block and checksum both.
The Hourly bock will skip-update 60 times, because it has not changed, and the minutes will use full cycles.
In the case of wearout failure, you simply shift from nearest minute, to nearest hour information (ie are less likely to have a full corruption)