Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 12 of 12

Thread: Increase write endurance on Teensy 4.0

  1. #1
    Junior Member
    Join Date
    Aug 2020
    Posts
    9

    Increase write endurance on Teensy 4.0

    Hello,

    I just need to store 32 bit to keep track of a counter. This counter is written relatively often to the eeprom, therefore I would like to increase the write endurance on the T4.
    I checked several threads in the forum like https://forum.pjrc.com/threads/57377...l=1#post214566 and https://forum.pjrc.com/threads/52433...f-program-data but those threads mainly deal with T3.x.

    I checked eeprom.c/eeprom.h and the only possible values to tweak are E2END,FLASH_BASEADDR and FLASH_SECTORS. No EEPARTITION or EEESPLIT or similar as stated in the above mentioned threads.
    So I'm a bit lost here. How can I increase the write endurance/wear leveling on the T4 when I just need to store 4 bytes?

    Thanks in advance
    Michael

  2. #2
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    140
    Sorry, I wrote an initial answer, then re-read your post & realized that you are storing a counter. The approach that I initially wrote would work for 4 independent byte values, but would not actually work for your counter. So, look at my next answer instead, which is a much cleaner (as well as more applicable) potential solution to your request !!

    Mark J Culross
    KD5RXT
    Last edited by kd5rxt-mark; 09-19-2020 at 05:57 PM. Reason: Unsuitalbe answer !!

  3. #3
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    140
    Quote Originally Posted by Codepoet View Post
    Hello,

    I just need to store 32 bit to keep track of a counter. This counter is written relatively often to the eeprom, therefore I would like to increase the write endurance on the T4.
    I checked several threads in the forum like https://forum.pjrc.com/threads/57377...l=1#post214566 and https://forum.pjrc.com/threads/52433...f-program-data but those threads mainly deal with T3.x.

    I checked eeprom.c/eeprom.h and the only possible values to tweak are E2END,FLASH_BASEADDR and FLASH_SECTORS. No EEPARTITION or EEESPLIT or similar as stated in the above mentioned threads.
    So I'm a bit lost here. How can I increase the write endurance/wear leveling on the T4 when I just need to store 4 bytes?

    Thanks in advance
    Michael
    Michael:

    Here's (a modified version of) an approach that I've used in the past on an Arduino for the exact same (wear leveling) purpose:

    1) perform a one-time prep on your EEPROM by writing 0xff to the first four locations of your EEPROM, (optionally) followed by the default/starting value of your counter
    2) each time you want to store a new counter, start reading from the very first location in EEPROM until you find four 0xff values in a row (call the location of the first 0xff ALOC for "anchor location")
    3) write 0x00 to ALOC
    4) write 0xff to ALOC+1 thru ALOC+4, taking care to "wrap" the calculation of where to write these flag values to account for the actual size of the EEPROM
    5) write your four byte values to ALOC+5 thru ALOC+8, taking care to "wrap" the calculation of where to write each byte to account for the actual size of the EEPROM

    Using this approach, each time you store a new counter, the starting location of the storage of your four bytes will creep its way thru the entire EEPROM. Take note that your counter value must be restricted from ever having a value of 0xffffffff, else that will be mistaken for the flag.

    Hope that helps. Good luck & have fun !!

    Mark J Culross
    KD5RXT

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,648
    Does the T_4.0 have an RTC battery installed? There are a couple of RTC storage bytes that maintain value across shutdown and reset as long as power it maintained.

    Those would allow continuous updates and static storage in that case without wear concern. The EEPROM could be used in a fashion like p#3 to spread ongoing writes across all of EEPROM before starting over at some slower rate to minimize the flash erase.

    Not sure if ALL of EEPROM should be cleared to 0xff before each pass starts as 0xff is the formatted state. When writing if zero bits can't be set to store the value that forces a 'block' write move. Otherwise as writes progress it could force a rewrite of that block to hold each new value and that may not result in the desired minimal rewrite.

    Have not ever looked at the underlying scheme - but it was tested with a sketch by a user in the T_4.0 Beta thread - using the PJRC provided code. Finding that code combined with the PJRC code might offer better insight. Getting blocks formatted before starting would assure only ongoing bits are written

  5. #5
    Senior Member
    Join Date
    Aug 2013
    Location
    Gothenburg, Sweden
    Posts
    329
    You could add a FRAM SPI serial ram nonvolatile storage chip, claiming 100 trillion read/write cycle endurance

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,648
    That EEPROM structure monitor program is linked in this post : forum.pjrc.com/threads/57377-TEENSY-4-0-EEPROM-amp-RAM-Questions - also some other notes there re; eeprom code

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,976
    Teensy 4.0 already does wear leveling. But it also maps certain emulated EEPROM addresses to particular 4K flash sectors, which greatly improves performance for 32 bit writes. You could maximize the wear leveling effect and also keep the performance improvement with a strategy based on the details of how the EEPROM emulation code does this mapping.

    The short answer is I'd recommend storing 15 copies of your counter. Put the first copy at address 0, the 2nd copy at address 4, 3rd at 8, and so on. At startup, read all 15 and whichever is largest must be the most recently written. Then as you write new values, always write to the next in the list, of course wrapping back to 0 when you get to the end of the list. This will take advantage of how the EEPROM emulation manages sectors to give you the best possible endurance.

    To explain a bit further, internally 15 sectors of the flash memory are used. Each sector maps to 72 bytes of the emulated EEPROM. Sector 0 is used for addresses 0 to 3, then 72 to 75, and 144 to 147, and so on. Sector 1 is used for addresses 4 to 7, 76 to 79, etc. As you write, both the actual data and address offset info is written to the underlying flash sector. So there's no point using EEPROM address past 71 if you only need to store a 4 byte counter. When you write to bytes 0 to 3, it will cause 8 bytes to written into the first sector. Then writing to 4-7 will write 8 bytes into the 2nd sector. This scheme was chosen so that 8, 16 and 32 bit writes can be done with only a single quick write to underlying flash. But use of more EEPROM will tend to spread across sectors, where 60 bytes is the ideal size which perfectly maps to equally wearing across all 15 sectors.

    As far as endurance improvement is concerned, each 32 bit write you perform will write 8 of 4096 bytes in each sector. That uses 1/512th of its endurance. Winbond specifies the W25Q16 chip at 100K write endurance. So the wear leveling will give 51.2 million writes of your 32 bit counter until you reach Winbond's spec, assuming you use this approach with 15 copies of your counter.

    If you will need to write more than 51.2 million times over the life of your board, you really should consider using the RTC's (NXP called it "SNVS") memory with a coin cell or large capacitor backup, or add one of those FRAM chips which gives incredible write endurance.

    You could also try adding an early warning detection of power loss. Usually this involves having circuitry which can monitor the power supply input voltage, so you can recognize power loss before the power supply's capacitors discharge.... with enough time to allow you to reliably back up the counter to EEPROM.

  8. #8
    Senior Member
    Join Date
    Dec 2013
    Location
    East Stroudsburg PA.
    Posts
    290
    Use Magnetoresistive RAM (MRAM).
    MRAM has unlimited endurance and infinite Read/Write cycles; FRAM Reads are destructive and eventually lead to wear-out.

    Everspin MRAM is available in a functional equivalent or drop-in replacement for most FRAM devices.
    Immediate (<1ns) Power-off with no loss of data.
    Unlimited read and write cycle endurance.
    Truly Asynchronous SRAM compatible speeds and cycle times.
    20-Year data retention with no cycling dependence.
    No wear-out concerns.

    https://www.digikey.com/product-deta...048-ND/4021226
    Last edited by Chris O.; 09-20-2020 at 03:20 AM. Reason: digikey link

  9. #9
    Junior Member
    Join Date
    Aug 2020
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    Teensy 4.0 already does wear leveling. But it also maps certain emulated EEPROM addresses to particular 4K flash sectors, which greatly improves performance for 32 bit writes. You could maximize the wear leveling effect and also keep the performance improvement with a strategy based on the details of how the EEPROM emulation code does this mapping.

    The short answer is I'd recommend storing 15 copies of your counter. Put the first copy at address 0, the 2nd copy at address 4, 3rd at 8, and so on. At startup, read all 15 and whichever is largest must be the most recently written. Then as you write new values, always write to the next in the list, of course wrapping back to 0 when you get to the end of the list. This will take advantage of how the EEPROM emulation manages sectors to give you the best possible endurance.

    To explain a bit further, internally 15 sectors of the flash memory are used. Each sector maps to 72 bytes of the emulated EEPROM. Sector 0 is used for addresses 0 to 3, then 72 to 75, and 144 to 147, and so on. Sector 1 is used for addresses 4 to 7, 76 to 79, etc. As you write, both the actual data and address offset info is written to the underlying flash sector. So there's no point using EEPROM address past 71 if you only need to store a 4 byte counter. When you write to bytes 0 to 3, it will cause 8 bytes to written into the first sector. Then writing to 4-7 will write 8 bytes into the 2nd sector. This scheme was chosen so that 8, 16 and 32 bit writes can be done with only a single quick write to underlying flash. But use of more EEPROM will tend to spread across sectors, where 60 bytes is the ideal size which perfectly maps to equally wearing across all 15 sectors.

    As far as endurance improvement is concerned, each 32 bit write you perform will write 8 of 4096 bytes in each sector. That uses 1/512th of its endurance. Winbond specifies the W25Q16 chip at 100K write endurance. So the wear leveling will give 51.2 million writes of your 32 bit counter until you reach Winbond's spec, assuming you use this approach with 15 copies of your counter.

    If you will need to write more than 51.2 million times over the life of your board, you really should consider using the RTC's (NXP called it "SNVS") memory with a coin cell or large capacitor backup, or add one of those FRAM chips which gives incredible write endurance.

    You could also try adding an early warning detection of power loss. Usually this involves having circuitry which can monitor the power supply input voltage, so you can recognize power loss before the power supply's capacitors discharge.... with enough time to allow you to reliably back up the counter to EEPROM.
    Thanks Paul, exactly what I was searching for. I already knew the Teensy does wear leveling but thought there is a possibility to somehow shrink the space in benefit of increased wear leveling. But this approach is as good. Only difference is that my counter can also decrease, so I cannot check for the highest counter.
    You write that 15 sectors are mapped to the addresses 4 byte wise. What about the addresses 60 to 71? What are they mapped to?

    If I find it still not enough write cycles I will consider using FRAM/MRAM. But my space is very limited so I think I have to stick with the EEProm/Flash approach.

    Thanks
    Michael

  10. #10
    Senior Member
    Join Date
    Jul 2020
    Posts
    459
    In that case write both your counter and another counter (or timestamp) that always increases, so that you can
    tell which is the latest position written.

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,976
    Quote Originally Posted by Codepoet View Post
    You write that 15 sectors are mapped to the addresses 4 byte wise. What about the addresses 60 to 71? What are they mapped to?
    Addresses 60 to 63 are mapped to the first flash sector, just like addresses 0 to 4 are. When you write a 32 bit number to either location, 8 bytes are actually written into the flash sector. 4 of those 8 bytes are your data. The other 4 are address info. So when you write to locations 60-63, those other 4 bytes are written differently than if had written to locations 0-3.

    When you read from emulated EEPROM, the emulation code immediately narrows the search to just one 4K sector, and then it must read those other 4 bytes to find the most recent copy of your data within the sector.

    That is why you should use exactly 15 copies of your counter in locations 0 to 59, and why there is no point to using any more beyond location 59. This isn't anything fundamental about how the flash or processor works... it's simply how I wrote the EEPROM emulation code. I considered other schemes which could have distributed wear across all 15 sectors (in a worst case only 1 sector gets all the wear while the other 14 go unsed), but they would have required more address data per byte. I also considered ways using less address info, and a variety of ideas to improve performance for various writing patterns. Ultimately I chose this approach which gives pretty good wear leveling for most of the common usage cases, and optimizes speed for the common usage of writing up to 32 bit numbers.

  12. #12
    Junior Member
    Join Date
    Aug 2020
    Posts
    9
    If I understood it correctly it can be visualized like follows (?)

    Click image for larger version. 

Name:	Teensy4_WearLevelling.jpg 
Views:	19 
Size:	50.2 KB 
ID:	21795

    Thanks
    Michael

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •