[Solved] How safe is save()?

Posted on
  • Hello,

    I want to store a variable on a regular basis so it is not lost after power loss.
    The easiest way is to store the complete state of the software with save(). However, this stores everything and I'm afraid that it breaks the flash if used too often.
    How often can I write into the flash? Would be every hour too much?

    Is there a better solution?
    The warnings at the flash documentation scare me :-)


  • Hi Sven,

    Yeah, it re-writes all of flash, so would eventually give you problems if you rewrite it every minute or so. Every hour might be Ok but it also ends up resetting your code each time, and if it failed to flash it could delete your code.

    You're best off using the FlashEEPROM module. That still stores data in flash, but it does it by adding just the new data and then erasing only when needed - so realistically it'll make flash last long enough that you shouldn't have to worry... And it doesn't reset or risk changing your code.

  • Thanks for the hint.
    But where can I find that module? http://www.espruino.com/Modules does not show it.

  • ...or you go for this FRAM/MRAM, which you can virtually not out write: 10^14 read/write cycles guarantee you 3+ years of 1000 writes per second... ;-) --- it is a bit more expensive than a pin compatible (Flash)EEPROM, but you can handle it like RAM - NO WRITE WAITS / DELAYS...

    In deed, you can use large FlashEEPROM and will practically never run out of working memory cells, but you have to write some algorithms to write into different spaces... Writing encoded -which will always flip a bit - you can use binary search to find the next free spot in decent time.

    The algorithm checks the 'byte in the middle of the space'. If it is not written, check the 'byte in the middle of the first half of the space', otherwise in the second half.... and so on, until you find the last written one. The encoding uses a little bit more space, but it is insignificant.

    If can think of fixed length sections, you flip bits in the first or last byte of the sections as used indicator and you go in the algorithm for sectors instead of bytes.The remaining part of the sections is for uncoded storage. You gain space by not encoding and loose some by the used indicator bytes.

    Since you want to write some meta data anyway - such as lengths and indicator for begin, end, and 'middle' block - it will make your day as used-indicator AND navigation / search information for reading back.

  • FlashEEPROM is here: http://www.espruino.com/FlashEEPROM

    Thanks for letting me know - I'll make sure it appears in that list

  • @allObjects: Are you talking about adding external memory? How much does those cost?

  • He's talking about external EEPROM or FRAM (depending on how often you have to write it, EEPROM may be fine - you get like 100k rewrites from EEPROM, infinite from FRAM; FRAM also writes instantly byte-by-byte, while EEPROM is written in pages - but the AT24/AT25 modules hide this from you). This is byte addressable storage that works over I2C or SPI
    EBay modules (I2C EEPROMs with breakout): http://www.ebay.com/sch/i.html?_nkw=eepr­om+at24
    Digikey chips: http://www.digikey.com/product-search/en­/integrated-circuits-ics/memory/2556980?­k=&pkeyword=&pv149=150&pv149=2&pv149=120­&pv149=55&pv149=20&FV=1c0002%2C1c0003%2C­1c0006%2Cf040003%2Cf040006%2Cf040009%2Cf­ff40027%2Cfff80434%2C268001d%2C268001f%2­C2680042%2C26802e4&mnonly=0&newproducts=­0&ColumnSort=0&page=1&stock=1&quantity=0­&ptm=0&fid=0&pageSize=25 (eeprom/FRAM/etc SPI and I2C memory chips)

    Note that essentially all of the I2C and SPI eeprom and fram chips on the market have the same interface, and can be used with the same Espruino module.

  • Thanks for all the information.
    But I started my first steps with the build-in flash using flash-eeprom module.

    Are there no convenience functions to convert any integer into Uint8Array and back? For strings, these functions are available.

  • What do you mean by that?

  • Try E.toUint8Array(), and E.toString() to do the conversions you need. (See the Reference page)

  • I want to store an integer using FlashEEPROM. However, only the lowest 8 bits are stored:

    > var f = new (require("FlashEEPROM"))();
    > f.write(1, 1025);
    > f.read(1);
    =new Uint8Array([1])

    E.toUint8Array() also doesn't help:

    =new Uint8Array([1])
  • @avanc, have a look at conversation about Interfacing -
    Writing and Reading 'persistent' data using FlashEEPROM (journaling) module
    . It may answer some of your questions and marvels...

  • Still wondering a little bit, that conversion to Uint8Array is available for some default data types (e.g. string) and not for others (e.g. integer or decimal).

    But shouldn't be that hard to write this functionality.

  • Ahh, yes - it's a bit annoying. The easiest way is to use the Typed Arrays... So:

    var a = new Uint8Array(8); // 8 bytes
    a.buffer // an 'untyped' buffer
    new Int32Array(a.buffer); // a 2 element, int array
    new Float32Array(a.buffer); // 2 element floating point array
    new Float64Array(a.buffer); // 1 element float array

    and so on... each of those arrays will act on the same data. You can also supply lengths and offsets

  • ... or perhaps there's no need to save the data in binary format? You could just convert it to a string with JSON.stringify and save that, then convert the string back with JSON.parse?

  • @avanc, @Gordon, resuming the topic at this stage of this thread in Interfacing -
    Writing and Reading 'persistent' data using FlashEEPROM (journaling) module
    ... which has nothing to do with save(); anymore and is of general interest.

  • @allObjects: You are right.

    Thanks for the advices!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

[Solved] How safe is save()?

Posted by Avatar for avanc @avanc