EEPROM for ESP8266
by kacang bawang
This article describes a small EEPROM emulation library that I wrote for ESP8266. It implements a very simple EEPROM emulation scheme that allows storing 16bit values. Each such 16bit value is found by its 16bit index.
For those no familiar with what EEPROM emulation is all about:
Flash can be written to 4 bytes at a time. But before doing so, it must be erased. Alas, erasing can only be done 4096 bytes at a time. You could erase all the 4096 bytes, then write whatever you need, and repeat this later, as needed. But there are two problems with that. One – erasing is slow. We want to finish a write as fast as we can, so that there’s less chance of being interrupted by something like a power outage. Two – you can only erase a given sector of flash about 10,000 times before it wears out. For something like a logging system, that is not a very large number.
To fix these two problems we devise the following scheme. We will write index/value pairs (4 bytes) into the larger flash page (4096 bytes) one after another. So, index=1 would not be an offset but rather a mark, that could appear more than once. The value corresponding to the last such entry would be the valid one. This way, we can write to index 1 for 4096 times before having to erase. Once the page is full, we find the latest values for every index, transfer them to the next page, and erase the old one. Now we are free to continue writing until the new page is also full. Needless to say, the minimum number of flash pages required is 2, but can be more. The more pages, the longer the flash will last. We trade space for longevity.
Let’s take a look at an example.
1 2 3 |
for (int i = 1; i < (4096/4)-1; i++) { //4 bytes per entry -> 1024 entries, one reserved eeprom_write(i%4, i); } |
What will the contents of the current eeprom flash page look like after the cycle completes? That's right, like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
0000: reserved 0004: 0,0 0008: 1,1 000C: 2,2 0010: 3,3 0014: 0,4 0018: 1,5 001C: 2,6 ... FFE4: 3,1019 FFE8: 0,1020 FFF0: 1,1021 FFFC: 2,1022 |
The first 4 bytes are reserved for status bytes, but otherwise we have written to the same 4 locations a bunch of times. Now the page is full. If there is another write, we will migrate to the second/next page first, to make room. So, let's continue the example:
1 |
eeprom_write(1023%4, 1023); |
What will the new flash page look like?
1 2 3 4 5 6 |
0000: reserved 0004: 0,1020 0008: 1,1021 000C: 2,1022 0010: 3,1019 0014: 3,1023 |
As you can see the most recent values have been moved over, and index 3 has been updated further. The process thus continues.
If we always write to the same location, and do so 5 times a minute, we have ~4 years before our 2 flash pages wear out (at 10000 writes each). If that is not enough for you, increase the number of pages dedicated to EEPROM and increase the endurance further.
The library can be found here:
EEPROM for ESP8266
Hi!
Thanks for the library – it is very useful!
I have one question: if we write 4 bytes at a time (2 bytes key, 2 bytes value), don’t we fill the page after 1023 writes not 4096 ((4096 – 4 status bytes) / 4)?
best regards,
Simon
Well, hot damn. Yeah… sorry about that. Let me
erase the evidencefix itHi,
I tried the code on FeeRTOS but i am not able to read and write the data into.
This command for flash :
esptool.py –port /dev/ttyUSB0 write_flash 0x00000 eagle.flash.bin 0x20000 eagle.irom0text.bin 0x7c000 esp_init_data_default.bin 0x7e000 blank.bin