Persisting state

Hi all!

Is there a correct way (library) to persist some variables (strings, integers, etc). Even after power off??

I need to store state and some configurations… Any clue welcomed!

1 Like

@frlobo, you could use the EEPROM emulation function that allocates 100 bytes of flash to act as eeprom. For more storage, you could use an external eeprom or FRAM module. :smile:

1 Like

Thanks!

What about the:
— 2MB of external flash; EEPROM supplied by CC3000

How can I access that?

@frlobo, the external EEPROM has serious limitations due to its 4KB sector size and its limited write/erase endurance (10,000). Take a look at this topic for more info:

I think it is 100,000 endurance which is not too bad if one just wants to store parameters or hold other software.

If the core stored its backup firmware (tinker app) in the external memory would that free up some more Internal memory? Its not like we change the backup firmware everyday

@bobtidey, the spec sheet show a minimum 10,000 cycle endurance :smile:

@Hootie81, the factory rest firmware IS in external flash already! :wink:

1 Like

I am days away from being able to offer a library that provides eeprom emulation using any amount up to 1.5MB of the external flash. There’s also different different storage mechanisms that trade-off number of erase cycles per address vs. storage density - in the best case you can emulate ca. 10^8 byte level rewrites.

(Although I’ve been talking about this for a while, I only got to start coding it last week. I’m just putting the finishing touches on the on-chip integration tests, and then have to package it as a library and make a nice makefile for the desktop unit and integration tests.)

5 Likes

Will we be able to select to save some data to the EEPROM at compile time?

E.g. large amounts of text for menus which will never change but otherwise occupy large amounts of precious RAM.

@NanoAkron, I believe you can use dfu-util to put data directly onto the external eeprom. It cannot be done at compile time and needs to be a separate process. I can’t however, seem to find the post talking about that!

@peekay123 Strange. The Silicon Storage Tech data sheet I have (S71271-02-000) for the SST25VF016B says 100,000 cycles endurance (typical) and 100 year retention. I realise factory s/w is in the flash already. I was thinking about holding lots more user level s/w in there like a disk system.

I guess what I was thinking was if there could be something like:

#EEPROM_start Hello
Hello World!
#EEPROM_end Hello

Precompiler instructions that would tell the flasher to ‘store this stuff in the EEPROM and make it available to the user as “Hello”’

Serial.println(EEPROM(Hello));

I’m guessing reading from the EEPROM doesn’t ‘consume’ it as quickly as read-writes…

Just to set the record straight, the internal flash is rated to 10k cycles (source - http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00165693.pdf section 3.2 wear levelling), and the external flash is 100k cycles (source).

@mdma, @zachary linked this SST model for the external eeprom! That datasheet is the one in the core hardware repo. It shows a 10,000 cycle endurance. So which one is correct? :open_mouth:

Sorry am I misunderstanding? I’m not seeing 10,000 for the external flash from that PDF data sheet you linked, it says on the first page:

• Superior Reliability
– Endurance: 100,000 Cycles (typical)
– Greater than 100 years Data Retention

The spark docs also says:

“Also, note that the maximum read-write endurance is limited to 100,000 cycles. meh.”

@mdma… arrrrgggghhh!!! First, I think I’m way too tired to read spec sheets right now. Second, I missed that part on the first page. Instead, I focused on table 12, page 23 that says 10,000. Geesh. I have got to get me better drugs :stuck_out_tongue:

1 Like

Hi @peekay123 and @mdma

You are both right, sort-of! The one datasheet says the endurance is 10,000 cycles minimum. The other datasheet says 100,000 cycles typical.

Endurance is not tested spec–that is, they cannot check each part for spec without wearing it out, so they do a statistical sample of a few parts and extrapolate. I am little surprised that there is only one order of magnitude between the values!

So 10,000 is guaranteed but you are likely to do a lot better than that typically.

3 Likes

@frlobo - I’ve put up a library that simplifies reading and writing to flash. Look out for flashee-eeprom in the online IDE.

It’s not officially “released” yet, but it makes writing to the flash easy:

FlashDevice* device = Devices::createWearLevelErase();
FlashWriter writer(device);

MyStruct[20] data = ...;  // your data
writer.write(data, sizeof(data));    
MyConfig[50] config = ...; 
writer.write(config, sizeof(config));
char myString[20];    // filled with string
writer.writeString(myString);

To read the data back

FlashDevice* device = Devices::createWearLevelErase();
FlashReader reader(device);

MyStruct[20] data = ...;  // your data
reader.read(data, sizeof(data));    
MyConfig[50] config = ...; 
reader.read(config, sizeof(config));
char myString[20];
reader.readString(myString);

The library takes care of a lot of the details of dealing with flash memory, - in this case that would be erasing pages when necessary, allowing writes to span page boundaries, keeping track of the current write/read address, and wear levelling, so that the the whole of the flash is used rather than wearing out the first few pages.

1 Like

Outstanding my friend!

Thank you for this…

Sorry for my ignorance… I am new with C…

MyStruct[20] data = ??? What kind of data? an array? string?
What does the [20] mean… 20 Characters? 20 ??

A little bit of help would be great!

Ah, sounds like you do need to know a little more C/C++. I’ll give you pointers, but it’s a good idea to become more familiar with the language and how the data is represented in memory.

The [20] means we have an array of 20 items. Maybe something like this:

struct MyConfig {
    int setting;            // these are just examples you said you had some configuration
    int numSensors;
    char[50]  aStringMaxLength50;  // and strings to store
    bool flag;    
}

This defines a structure, that you can build in memory,

MyConfig[20] configs;   // let's say you want to store 20 of these
// now let's set up the first one
configs[0].numSensors = 2;
configs[0].setting = 42;
strncpy(configs[0].aStringMaxLength50, "A configuration string");
configs[0].flag = true;

and then store to flash using the code I posted above.

Here’s a question for you to try to find the answer to, which might help you learn more C++: In the structure above, I wrote char[50] aStringMaxLength50 - strings can also be represented as char* - so why did I not write char* aStringMaxLength50? When you search for the answer to this it will help you learn about how C uses memory.

2 Likes