Retained Memory for Boron/Argon/Xenon

I’ve gotten used to using retained variables on my electron-based devices, but now I am switching to the Boron and mesh devices.

It seems like you can’t have retained variables on the mesh devices like you could with the Electron, but certainly there is a way? For example on my Electron devices I will setup a retained int for log_interval and set it remotely using a particle variable. This way when it wakes up from sleep (SLEEP_MODE_DEEP on the Electron) it remembers what the log_interval was set to and continues to function as intended. I am sure there is a way to do this on the mesh series devices, I just don’t know how!

AFAIK the SLEEP_MODE_DEEP sleep on the Boron cannot keep track of time to wake itself up, so I think I will just be using the “stop mode” sleep System.sleep(pin, edge, timeout)… perhaps this sleep mode retains all RAM… but I’d still like to know how to retain variables if the device is shut off, like with the EN pin for example…

I have seen a couple other posts about thus topic but they all seem to die out before we get a hard answer?

Thanks for the help.

Pulling the EN pin low would be the same as removing the battery from the Electron in both cases retained variables would vanish.

Gen3 devices do also support retained variables although undocumented and due to the "half baked nature" of the feature the initialisation can currently not done the in the variable declaration but you'd need to write some code that initialises only on first boot.

Here is an issue report about the initialisation problem
https://github.com/particle-iot/device-os/issues/1919

So maybe EEPROM is the only on-board answer?

That depends on the exact nature of the question :wink:

At first I just want to be able to set my logging interval with a Particle.variable() and have it remember just like the retained variables on the electron.

I think the sleep mode System.sleep(pin, edge, timeout) I will be using keeps the RAM intact anyways, correct?

So if that part is solved… say I wanted to retain some variables AFTER pulling the EN pin low, EEPROM would suffice?

Yup, when going with the EN pin (or other means to completele depower the device) EEPROM would be my first choice

What kind of data are you trying to store?
The Gen 3 (Argon, Boron, Xenon) devices have 4096 bytes of emulated EEPROM.
On the nRF52 , flash write endurance is about 10,000 cycles, you can get more by using a round robin or random storage technique. Assuming your data is small. And you can always read flash as much as you want.
With your log_interval example, just write it to eeprom 0 using a “read before write” and you should be fine.

I will mostly be writing a few ints. Very basic like log interval, address select, probably a maximum of 10 ints in EEPROM.

AFAIK, round robin is already implemented in the Particle base firmware for any EEPROM write operation.

1 Like

@tommy_boy you are correct. Here are my notes on Gen2/Gen3 emulated EEPROM.

For Gen 2:The emulated EEPROM does not use fixed cells, so, for example, there's no difference between writing each of the 2047 cells once, or writing a single address 2047 times.The EEPROM emulation uses two NOR flash pages, 16Kbytes each. Each write uses approximately twice the write size. So if you write 10 bytes, assume 20 bytes will be written to flash.The writes are essentially a journal of the changes, and each journal fill up the 16Kbyte flash page until full. Then the states is saved in the other flash sector and a new journal started.

Say you’re writing 10 bytes of data to a given EEPROM location. Given the 2x overhead, that will use 20 bytes of flash. Thus the first 614 times you write the data, you won’t cause a flash erase because you keep using up the free space in the sector of flash.

In other words, for a 10 byte write, the wear is one erase-write cycle for every 614 times you put data to the EEPROM, not every time you write. And there are two flash sectors, so the wear on each sector is half that.


On Gen3, EEPROM is just a file on the LittleFS file system. There's wear-leveling in LittleFS, and the writes are spread out across the 2 Mbyte area with 512 byte sectors, so across 4096 sectors. Since there are so many sectors, wear shouldn't be much of an issue in most cases.

4 Likes

So on the Gen 3 devices, we do have access to the entire 4096 bytes of EEPROM, and we don’t have to worry about write wear as much as on the Gen 2 systems?

That is correct.

I am using EEPROM-Storage with the Argon, instructions and examples are very easy to follow, easy to store and retrieve in EEPROM Strings, floats, etc.:
Particle EEPROM-Storage