Jump to content
Sign in to follow this  
ElTita

Flash memory can be damaged by writes? (and related things)

Recommended Posts

Hi, it's my firts post, sorry by my English.

I need make a temperature sensor that logs in flash memory sensed temperutes, say every 5 minutes. This logs, are read sensed by serial comunication.

Something like this:

int cantLogs = 0;
//called repeatedly by a control routine
void loopSensor()
{
int temp = readTemp();
cantLogs++;

storeTemp(cantLogs, temp);

sleep(5 minutes)

}

//storeTemp save temp in flash, and ALSO save position (that is, the last position used)

void storeTemp (int position, int temp)
{
....
}
//that fuction when is called read all temps and sends it by the serial line (it DON'T use variable 
//cantLogs, it needs know how much logs are here reading that info from memory flash)

void readTemps()
{
....
 
}

Ok, I think that I need is a data structure like this, using diferent flash segments; one for control data (last position used) and othes for the data itselft:
<pre>

ControlSegment = [lastPositionUsedInDataSegments,.........(maybe other info)....]

DataSegments = [temp1, temp2.....tempN] [temPN+1,..... Temp2N-1][... and so on...]

</pre>

Well.... bytes in DataSegments are written sequentially, and lastPostionUsedInDataSegments in ControlSegment needs to be updated every time one temp is logged....So:
- Do I need erase data segments previous the first write? And between writes in the same segment? (that is; i have logged temp1; now a I need log temp2, do I need do something special between these writes?

- How to updates in lastPositionUsedInDataSegments must be implemented? (erase all segment and then write the first bytes?)

- And finally.... reading 7.3.3 Writing Flash Memory in "MSP430x2xx Family  User's Guide" I found that:

 

 

Both write modes use a sequence of individual write instructions, but using the block write mode is approximately twice as fast as byte or word mode, because the voltage generator remains on for the complete block write. Any instruction that modifies a destination can be used to modify a flash location in either byte or word write mode or block write mode. A flash word (low and high bytes) must not be written more than twice between erasures. Otherwise, damage can occur.

WTF? If, for example, I write 3 times lastPositionUsedInDataSegments (firt bytes in a flash segment) without call "erase segment" fuction I can damage my flash memory?????

guide: http://www.ti.com/lit/ug/slau144j/slau144j.pdf

 

Thanks!

P.S: if someone have some real code doing something similar (I think that it is a usual situation: log persistently sensed data for subsequent ) I will appreciate it.

 

 

 

Share this post


Link to post
Share on other sites

Flash will wear out after being erased and written many times. As a practical matter you will have to keep the pointer to the flash in RAM.

 

This would be a good application for one of the FRAM MSP430s. They have essentially unlimited write endurance.

Share this post


Link to post
Share on other sites

Keeping pointer in RAM would be good move if you could.

 

If you can't, can you get away with not storing a pointer at all?

When you need to add a reading, search for the the end of where readings already are - takes more time, and have to reserve one reading value to mean there is no reading, but don't have to store the pointer.  Using binary search should be able to find the end in order of log2(maximum number of samples).  (One of the examples below just used a simple linear search.)

 

I have definitely seen a temperature logger for the MSP430 using flash a long time ago.

 

This isn't the one I was thinking of, but similar concept.

http://benlo.com/msp430/

 

Here is another one - which seemed to be unavailable at the moment, so I went to an archived version:

https://web.archive.org/web/20130923235655/http://hiwaay.net/~bzwilson/temp_recorder/

Share this post


Link to post
Share on other sites

 

Both write modes use a sequence of individual write instructions, but using the block write mode is approximately twice as fast as byte or word mode, because the voltage generator remains on for the complete block write. Any instruction that modifies a destination can be used to modify a flash location in either byte or word write mode or block write mode. A flash word (low and high bytes) must not be written more than twice between erasures. Otherwise, damage can occur.

 

WTF? If, for example, I write 3 times lastPositionUsedInDataSegments (firt bytes in a flash segment) without call "erase segment" fuction I can damage my flash memory?????

 

 

As I understand it, the "damage" referred to here is to the data contained in the same segment, not physical damage to the flash memory hardware. Repeated overwrites without erase can disturb the contents of nearby flash cells. The same can happen if the maximum cumulative programming time is exceeded.

 

Flash memory does get damaged physically by writing (particularly the erase process). The MSP430G2553 datasheet guarantees at least 10000 erase cycles per segment without damage.

Share this post


Link to post
Share on other sites

Most flash memory can only be written to 0 values in their bits, the erase cycle will set all bits to 1 again. So writing a byte, say 10101010 and then writing 01010101 will result in a byte read as 00000000. To avoid such behaviour, you should always erase between write cycles. Alternatively, always write 11111111 to any byte you do not want to touch.

Also, as suggested before, try not to keep bookkeeping data in flash (like the end-of-array-pointer). Instead, make sure the default value after erasing is not a valid statement, as a result, you can determine the end of your array by iterating over it to check for this end value.

 

@@hmjswt You could do that... but why? There is flash and EEPROM-emulating-flash in these chips. Replacing the microcontroller is probably cheaper these days than adding more components in case the EEPROM dies. As suggested before, using an FRAM part would be nice too, since there is no real difference between RAM and flash on those, it's non-volatile RAM.

Share this post


Link to post
Share on other sites

@@roadrunner84

 

I use EEPROM for my temperature sensor logging.

It gives a lot of memory for little money.

I have to have an EEPROM dying on me yet.

An 512Kbit EEPROM costs about 1 Euro.

For my projects I make a stand-alone 2553 and EEPROM.

I communicate by Bluetooth.

Works very nicely.

And I can read the data by using TeraTerm or graphing it in Processing in real time.

Well, it works for me.

And using EEPROM is really simple and uses almost no memory.

So you have more memory for your program.

 

Nice to meet a fellow country man on this forum.

Share this post


Link to post
Share on other sites

He does have a point - 512Kb! There's probably bigger for little price increase.

Do note that it's common for FRAM chips to have 64KB FRAM size (code consumes a bit of it)

Share this post


Link to post
Share on other sites

Hallo,

 

Yes, there are bigger ones.

I am using 1024 Bits EEPROMS.

Costs less then $3.00.

You can chain 8 IC's for a total of 8Megabits!.

 

Works like a dream.

 

I have a page about EEPROMS and the LaunchPad on my website.

A lot is in dutch but I translated the EEPROM page in English.

You can download the source code.

http://swtcomp.com/launchpad/eeprom/eeprom.htm

Share this post


Link to post
Share on other sites

He does have a point - 512Kb! There's probably bigger for little price increase.

 

Do note that it's common for FRAM chips to have 64KB FRAM size (code consumes a bit of it)

If you're in need of big memory, then yes. But in most cases you'd need to log only a dozen or so entries, then using on-chip memory is much more interesting.

Also, note it's 512 kilobits, so that's 64 kilobytes. Still quite a bit of space. If you really need a LOT of memory, you could also consider using an SD card instead. SD cards are essentially just serial flash, not so different from EEPROMs. If you ditch the FAT filesystem, you don't need that much code to use them at all!

Share this post


Link to post
Share on other sites

I noticed it was in bits :P

Man the SD cards. I know that if I just need to store data in my own system I can ignore the FAT system but I still never understood how to interface with a SD card (well it's by SPI, or something like that).

If we're talking power wise - the EEPROM consumes less than the flash no? (not sure really)

Share this post


Link to post
Share on other sites

Thans to all!

@@oPossum using a pointer in ram, well, it will be lost after a power off and I think power off the device

About use a FRAM MSP430s, I think my launchad don't support these (anyway I don't have money for the moment, but I will consider it in the future)

@@hmjswt Do you know if a external  EEPROM can be used with a MSP430G2553?

EDIT: ohhhhh , yeah, thanks for the link!

 

Most flash memory can only be written to 0 values in their bits, the erase cycle will set all bits to 1 again. So writing a byte, say 10101010 and then writing 01010101 will result in a byte read as 00000000. To avoid such behaviour, you should always erase between write cycles. Alternatively, always write 11111111 to any byte you do not want to touch.

Also, as suggested before, try not to keep bookkeeping data in flash (like the end-of-array-pointer). Instead, make sure the default value after erasing is not a valid statement, as a result, you can determine the end of your array by iterating over it to check for this end value.

 

 

 

Good point! After a erase, the segments will  have all 1's, AND probably I will log 10 bits values in two bytes (the analog to digital converter have 10 bits)

I think something like that:

//called in power on, then this position is stored and updated in RAM
int findEndOfDataPoisition()
{
unsigned char * init = FIRST_BYTE_OF_DATA_SEGMENTS;
int position = 0;
while ((position < MAX_POSITION && *(init+position)!=0xFF)
{   position +=2; }
if (position < MAX_POSITION)
 return position; 
else
 return MAX_POSITION; //log full.... what to do?
}

 
As I understand it, the "damage" referred to here is to the data contained in the same segment, not physical damage to the flash memory hardware. Repeated overwrites without erase can disturb the contents of nearby flash cells. The same can happen if the maximum cumulative programming time is exceeded.
 
Flash memory does get damaged physically by writing (particularly the erase process). The MSP430G2553 datasheet guarantees at least 10000 erase cycles per segment without damage.

Are you sure? If that is the case, well, documentation is very poor.... one thing is "data can be corrupted" o other very different  "damage can occur"

 

In any case (damage or corruption data) it must be pointed that example of use of library MspFlash is very dangerous (it allows multiples writes without erases....):

#include "MspFlash.h"


// Two options to use for flash: One of the info flash segments, or a part of the program memory
// either define a bit of constant program memory, and pass a pointer to the start of a segment to the flash functions,

//*** Option 1: use program memory, uncomment these lines and you have 512 bytes of flash available (1024 bytes allocated) ****
//const unsigned char data[2*SEGMENT_SIZE] = {0};
//#define flash SEGPTR(data)
//

//*** Option 2: use one of the 64 byte info segments, uncomment this line. Use SEGMENT_B, SEGMENT_C or SEGMENT_D (each 64 bytes, 192 bytes in total)
#define flash SEGMENT_D
//


void setup() 
{
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly: 
  if ( Serial.available() )
  {
    switch ( Serial.read() )
    { 
      case 'e': doErase(); break;  
      case 'r': doRead(); break; 
      case 'w': doWrite(); break; 
      case 10:
      case 13: break;
      default: doHelp();
    }
  }  
}

void doRead()
{
  unsigned char p = 0;
  int i=0;
  Serial.println("Read:");
  do
  {
    Flash.read(flash+i, &p, 1);
    Serial.write(p);
    Serial.print(":");    
    Serial.println(p);
  } while ( p && (i++ < 16) );
  Serial.println(".");
}


void doErase()
{
 Serial.println("Erase"); 
 Flash.erase(flash); 
 Serial.println("Done."); 
}

void doWrite()
{
 Serial.println("Write");
 Flash.write(flash, (unsigned char*) "Hello World!" ,13); 
 Serial.println("Done.");
}

void doHelp()
{
  int div = (F_CPU/400000L) & 63; 
  Serial.println("flash test: e, r, w");
  Serial.println(F_CPU);
  Serial.println(div); 
}

About 10000 cycles write-erase per segment... well 10000*5/(60*24)= 34 days of time of life.... ouch.... (ok, i can store the end of array, say every hour and/or when it is externally ordered, but I don't see that very elegant...)

Share this post


Link to post
Share on other sites

I noticed it was in bits :P

 

Man the SD cards. I know that if I just need to store data in my own system I can ignore the FAT system but I still never understood how to interface with a SD card (well it's by SPI, or something like that).

 

If we're talking power wise - the EEPROM consumes less than the flash no? (not sure really)

It's quite simple actually. A serial flash chip is connected through SPI to your controller.

SPI is a set of 4 signals, a data line to the slave chip (MOSI; master out slave in) a data line from the slave chip (MISO; master in slave out), a clock line to the slave chip and a select line.

The select line determines which slave chip is going to respond to the data and also signifies the start of the data. The MISO and MOSI lines carry a contiguous stream of bits, making up a stream of bytes.

Since the slave knows when the data started (the moment the select line gone low), it will interpret the first byte or bytes of data as command, the rest as payload.

This could be, for example, a command telling to store data on a certain point in flash memory, followed by a bunch of data. It could be a read command, an erase command or stuff like a question "how much data can you store".

As a programmer you have very little to do with the MOSI, MISO and clock lines, those are taken care of by your SPI peripheral in your microcontroller. The select line on the other hand is in a lot of cases controlled from software. So you'd need to drive the select line prior to issuing a command to the SPI device.

 

Serial flash stores data in sectors, those are a few hundred bytes, 256, 512, 1024 and 2048 are common sizes. Whenever data is stored or erased, it must be in chunks of this size, so to alter data you must read an entire sector, then erase it and store the modified version back again.

For SD cards, erasing cannot be done in sectors, but in much larger blocks of several kilobytes. Writing can still occur on sector lever though. Another difference between SD cards and serial flash is that the "dialect" is uniform for all SD cards, while serial flash might sport different command values to get things done.

Also, SD card are specified to use a version of FAT as their filesystem (FAT16 for SD, FAT32 for SDHC and exFAT for SDXC), for which the FAT16 and FAT32 are royalty free. FAT stores files in small chunks of (mostly) 4kB, but those chunks may be scattered on the storage. To retrieve a file, you must look up where the next chunk is in the directory (folder). As an end user you see only the first chunk described, since that holds the filename and dates and attributes (read only etc). The other chunks hold where the next chunk is to be found. As a result, you'll be hopping back and forth between the directory and the file chunks unless you have so much memory that you can keep the directory in cache.

 

When ignoring the SD card specification to use FAT, you can store logging data in contiguous storage on the card, just make sure all of it is erased prior to writing. The only limitation that still holds is that you cannot read data fromthe SD card while in the middle of writing to a single 512 byte sector, since you cannot resume writing to it reliably.

Share this post


Link to post
Share on other sites

I suspect the flash memory inside the MSP devices was never INTENDED to be used this way. In a typical product the flash may be altered for config purposes or to update the program code. this will never get near the 10,000 write endurance.

 

So while it is possible. it may not have the lifetime you expect.

 

Are you sure? If that is the case, well, documentation is very poor.... one thing is "data can be corrupted" o other very different  "damage can occur"

 

.....

 

 

About 10000 cycles write-erase per segment... well 10000*5/(60*24)= 34 days of time of life.... ouch.... (ok, i can store the end of array, say every hour and/or when it is externally ordered, but I don't see that very elegant...)

 

I would expect that infact the datasheet is talking about multiple write to the same location without an erase. Which will "damage" your data, not the device itself.

 

If 34 days is not long enough. then I would consider using an external EEPROM IC. these are typically designed for 100,000 write cycles. Which for the same example will result in 10x the life.

 

If this still is not enough then investing in a FRAM series MSP430 would be a very good choice. These have (essentially) infinite endurance, and will maintain data without power.

Share this post


Link to post
Share on other sites

About 10000 cycles write-erase per segment... well 10000*5/(60*24)= 34 days of time of life.... ouch.... (ok, i can store the end of array, say every hour and/or when it is externally ordered, but I don't see that very elegant...)

 

That estimate is based on erasing the segment every time you write a single value (because you're updating "end of array" stored in flash). If you use findEndOfDataPoisition on startup you don't need the end of array stored in flash any more. You can then write your log data as 16-bit words, only erasing when starting a new segment of log data.

 

If you're writing to the information memory segments on MSP430G2553, you'd be writing 32 temperature measurements per erase. In that case the memory would last for at least 1088 days. If you allocated some of main memory instead you'd get 256 measurements stored per erase, which would be over 23 years endurance.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×