7
\$\begingroup\$

As I understand it, the life of an EEPROMs is usually rated at a certain number (e.g. 100k) of writes. Is this "per byte" or writes to the EEPROM system as a whole?

E.g. If the EEPROM has 4k bytes, could I conceivably make 400 million writes if they were evenly distributed?

Specifically, I'm talking about the EEPROM in the Arduino Mega 1280/2560.


Debrief: Thank you stevenvh and Majenko for your helpful explanations. I asked because I wanted to know whether I needed to bother updating only dirty variables when saving a lot of data (a large configuration). From a wear perspective, the answer seems to be 'no': wear happens at the "bit level" and is only caused by setting bits to zero. From a speed perspective, perhaps it would make sense to minimise the size of writes, but if this is not a consideration for your application, then you needn't stress out about it.

\$\endgroup\$

4 Answers 4

14
\$\begingroup\$

It's not just write cycles that's specified, but erase/write cycles. On the AVR EEPROM can be erased by byte. Erasing sets all bits to 1, writing selectively clears bits. You can't program a 1, just 0s. If you want to set at least one bit to 1 you have to erase that byte.
Erasing removes the charges from the FET's floating gate, but on each erase cycle some of the charge remains on the floating gate, which won't be removed through the quantum tunneling. This charges accumulates and after a number of cycles there's so much charge left on the floating gate that the bit still will read 0 after erasure. That's what determines EEPROM life, it's erasure rather than writing. So you can safely write additional 0s, as long as you don't erase.
As a result, if the datasheet specifies 100k erase/write cycles you can have maximum 800k write cycles, one bit at a time, for 100k erasures.

If you're using only part of the EEPROM memory space you can extend its life by distributing the data, like Matt says this is called wear leveling.
The simplest method of wear leveling when writing blocks of data is to include a counter with the data. Suppose you need to keep 14 bytes of data. Add a 17-bit counter as two bytes, you probably have a bit to spare for the 17th bit. Increment the counter before writing the block of 16 bytes. If the counter has reached 100 000 you know this block is becoming unreliable, so you move to the next 16 bytes. Use this until it is worn as well. And so on. A 4k memory consists of 256 sixteen byte blocks, so you can extend the original 100k cycles to 25 million.
It should be obvious that your gain is greater with smaller blocks of data.

further reading
data retention on a microcontroller

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Wow. Thanks so much for your comprehensive answer. \$\endgroup\$
    – aaaidan
    Commented Oct 23, 2011 at 23:34
  • 1
    \$\begingroup\$ What about EEPROM pages? ATmega328 datasheet p349 says that the EEPROM has 4-byte "pages." What does that mean? Does that mean that each time you write in any 1 of the 4 bytes in a page it has to rewrite the whole page? If so, this could mean that writing 1 time to each of the 4 bytes causes the entire page to be written 4 times more often, so writing one time to each of the 4 bytes in a page is actually 4 writes to each of those cells. Yes? No? Explanation? \$\endgroup\$ Commented Mar 22, 2018 at 5:07
5
\$\begingroup\$

It is per bit - or more specifically - per gate.

What you propose is known as "wear levelling" and is commonly used to extend the life of flash memory - especially SSD drives.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Can most EEPROMs erase a single bit? I thought the smallest write they could perform was a byte. \$\endgroup\$ Commented Oct 23, 2011 at 9:42
  • 4
    \$\begingroup\$ When you erase an eeprom you set it to all 1's. When you write to an eeprom you change the 1's to 0's - so writing 0b11111110 will infact only be changing one bit. Yes, you are 'writing' a byte, but only a single bit is being changed - thus only that bit is being worn out. \$\endgroup\$
    – Majenko
    Commented Oct 23, 2011 at 9:53
4
\$\begingroup\$

There are some variations in flash and EEPROM technology, but at least with some flash technologies, hitting a bit with just enough "oomph" to write a zero and then later hitting it with just enough "oomph" to write a "1" would typically not cause a whole lot of wear. On the other hand, hitting a bit with an excessive amount of energy to erase it can cause considerable wear. Unfortunately, it's not practical to regulate the precise amount of energy used to write and erase individual bits. Instead, one must hit an entire block with an "erase" pulse at once, and even if every bit were identically programmed, some bits will erase faster than others. If one weren't interested in erase speed and one had the ability to read bits as being 1/2-charged, 1/4 charged, 1/8 charged, or less, it might be possible to improve endurance by hitting the entire array with a short erase pulse and then, if every bit was more than 1/4 charged, hitting all the bits that were at less than 1/8 charged with a pulse that would charge them by about 1/8 (so that they would end up between 1/8 and 1/4 charged), then hitting the entire array with another erase pulse, etc. until no bit was more than 1/4 charged. Such an approach would avoid over-erasure, which is one of the major wear factors on flash memory. Unfortunately, such an approach not only add complexity--it would probably at least double erasure times, and probably increase them more than that.

\$\endgroup\$
0
\$\begingroup\$

The 17 bit wear level counter idea is not exactly correct. The idea was that you maintain a 17 bit counter to keep track of how many times you have written to a block of bytes, say 16 bytes. Every time you write to that set of 16 bytes you increment the 17 bit wear leveling counter. When the counter reaches 100000, you know you should move to 16 bytes in another part of the EEPROM so you get better reliability.

That would appear to be correct at first, but what about wear leveling on the 17 bit counter itself? Once you have incremented the 17 bit counter 100000 times it begins to wear out also. To fix this, maintain a second counter, say 16 bits (2 bytes). Every time the 17 bit counter reaches 100000 and you move to a different set of 16 bytes for the data, increment that counter and use that count to address a NEW set of 17 bits for the new wear leveling counter. That should work for a huge number of rewrites/erasures.

There is one more little issue though. I am not sure if 100000 is a good wear leveling count to use as the threshold for switching to a different set of data bytes. That i think is at 25 degrees C. That would mean to be sure you should probably use half of that, like 50000, and that should be ok. Testing would be a good idea though to make sure that works as expected at the temperatures you intend to run your chip at.

Sincerely, MrAl

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.