This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430g2553 flash erase and write

Other Parts Discussed in Thread: MSP430G2553

I understand that, before I can write to flash, I have to erase the entire segment.  My question is: 

I am trying to write integers to flash every 0.1 seconds.  The data comes in from the ADC.  If I erase the blocks I want to use at the very beginning of my main function, and then write the data as it comes in, do I have to erase every time?  Or can I do this:

void main()
{

      int x = 0;

      erase_flash();
      while(true)
      {

         do other stuff...

          x = read_data();
         write_flash(x);

      }

}

Where we can assume that I've already written the functions erase_flash, read_data, and write_flash, and that I'm addressing everything correctly.

I guess the question is: do I only need to erase the whole segment once in the program?

Mike

  • You are correct. You only need to erase one (or more) segment once and you can write one byte or one word at a time until that segment (or those segments) are all written.

  • Thanks,

    out of curiosity, why do I have to erase first?  I figure it's a design choice in the uC, but I can't figure out why.

    Mike

  • Mike:

    As I understand flash, when it is erased, it is all 1's (or all F's)...

    When you write to flash, you take selected 1's, and make them 0's. There is no way to take a 0 and make it into a 1 without a "mass erase," which takes a block of flash and erases the whole flash. (Makes all flash in that segment 1's.)

    So, when you want to reuse a segment, you need to make that segment all 1's before you can take selected bits to 0.

    Hopefully, that helps.

  • It is a compromise in the type of memory used. In this case they are using the so called Flash memory. There are some MSP430 that use so called FRAM memory. That type does not need erase and yet is non-volatile.

    Note that at one byte per 0.1 second, MSP430G2553 can only last a few seconds and the Flash memory will be full. You may want to look for a chip with more Flash memory or FRAM memory. For the latter, look for MSP430FR5xxx.

  • Thank you both, yes that explains things quite well.

    old_cow_yellow: I'd love to, but we're stuck with this hardware :-P It's part of a course and the students are required to learn to use the MSP430g2553.  I need to figure out a way to squeeze some more laboratory exercises out of existing hardware.  By my calculations, I have 6 bytes every 0.1 seconds.  If I blocked off 5120 bytes (10 segments), I should have enough for around 80 seconds of data before I run out of memory.  That is plenty for the lab I'm writing, unless I've done a miscalculation?

    Now, I'm coming up against a very strange problem: sometimes the memory is written and no issues are present.  However, sometimes strange things happen.  I'm looking at the disassembly window in IAR and looking directly at my flash memory.  The way I am testing my code is by writing the number of the address to each flash location (ie: 0C000 is number 0, 0C004 is number 4 and so forth).  The problem is: my flash memory isn't doing that.

    First, it doesn't make any sense that, if I'm storing ints, then 0C000 is the first address and 0C001 is the next one.  It should be 0C002 (2 bytes).  However, if I address using this two-byte addressing, I end up filling only half of my allocated memory on a good run, *and* i'm able to store ints where appropriate.  

    Second, if I store the numbers from 1 to n, where n is the number of addresses I've allocated, then 0C000 stores 1 and 0C001 stores 2.  The weird thing is that at 0C201 (513 memory addresses later, where Bytes should overflow), I am indeed storing the number 513, and then at 0C202 I store the number 514 and so on.

    Does the addressing work  intelligently on the g2553?  Does it know that, since I'm storing ints and using an int pointer, then adding one to an int pointer is equivalent to addressing the next available *int* storing space?  if that's the case, then why does the memory addressing (which are just numbers...) go up in increments of 1 but still end up storing the whole int?

    The whole thing is made even more confusing by the fact that I really can only store half of the memory addresses!  In theory, I should be at D400 when I'm done writing 5120 integers, but I end up at DC02 and then my program crashes as I start to enter where the code went (I allocated myself a bit more memory since my code is only 1000 bytes).

    Does any of this make sense?

    Mike

    EDIT: corrected addresses

  • Ah, I confused myself:

    0xC000 is the starting address and 0xC002 is, indeed, where the next integer is stored.  However, if:

    int *addr = 0xC000;

    is a pointer to the starting address, then addr+1 is the *next integer* that can be stored in memory.  I'm using word-addresses, not byte addresses, and thus why all of that stuff happened.  Oops.

    Mike

  • Note that if you start at 0xC000, you should erase at most 7 segments. The 8th has the Reset Vector, and possibly some Interrupt Vectors in it. If you erase those, you will get into troubles.

  • Michael Stachowsky said:
    Does it know that, since I'm storing ints and using an int pointer, then adding one to an int pointer is equivalent to addressing the next available *int* storing space?

    This is defined in the C standard.

    If you have an int*x, doing x++ will increment the value of x by the size of an int (2). Also x[y] will actually address (x+2y) then.
    x=x+1, however, will result in x incremented by 1 (so it is different from x++!)

    The MSPs, however, have another ‘feature’: if you use a word instruction on an odd address, the LSB is silently ignored. The MSP can do word or dword instruction only on even addresses, even if the assembly code contains an odd address.
    If you pass a pointer to a function, the compiler does not know whether it is an odd or even address. It does, however, assume that an ‘incoming’ pointer to int (or long int) will always be an even number. This makes problems when you convert a void* or char* to an int* before passing it (especially if the source data is a buffer with mixed data, or a stream).

    Pointer arithmetic in C is powerful, but risky.

**Attention** This is a public forum