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.

Storing an array in flash

Other Parts Discussed in Thread: MSP430G2553

I am developing firmware for a simple application for the MSP430G2553 which accepts a four digit passcode and stores it in memory. I had a working example but now I need the uC to store the passcode in flash so that it is preserved even when power to the chip is off (IE: batteries run out or some other power failure occurs). I am having trouble understanding the code needed to initialize an array in flash memory at a specific location in flash (I want to stay well away from the calibration data and program data). I want to initialize an array of 4 integers beginning at info memory segment B (which I understand to be somewhere around 0x10BF and lower to 0x107F) and then be able to read the data as if it were a normal array. I am still trying to grasp the concept of pointers in C (I am a novice programmer) and my attempts at accomplishing the above goal include creating an array of pointers like so:

int* array[4] = { (int*) 0x10BF, (int*) 0x10AF, (int*) 0x109F, (int*) 0x108F};

I then store values in these flash locations (at least I think I do) using code similar to TI examples given for this device series (flashwrite_01.c or whatever). When I try to read the values, they do not appear to be the same data which I had written to the locations. Would the problem be that it is not an unsigned integer array and these hex values try to represent negative values? And making the array constant makes me unable to write to it (at least the way I am doing it), I understand that it should be initializing a constant array of pointers which indicate an address in memory, but I don't know what I'm doing wrong. I am unable to post my exact code (the example above is what I can recall from memory, no pun intended) as I am away from my developing computer. I am sorry to be such a noobie but other topics which I have found do not address my exact problem and I do not wish to edit the .cmd file to set the starting address for flash writing. If you would like code examples I will be able to post them later, thank you!

TL;DR: I wish to initialize an array of pointers which point to four addresses in flash memory starting at info block b to store four integer values, how would initialize/use the array to read as if it were a regular array? What is the best method to accomplish this?

Platform: MSP430G2553

IDE: CCS V4.0

  • Hi Don,

    To read from the flash memory, simply declare a pointer to the memory location, eg.

    char * flash_ptr = (char *) 0x1000; // beginning of Info D

    then you would read the data by dereferencing the pointer, as in

    char temp = *flash_ptr; // read first byte of Info D

    You can expand this by doing pointer arithmetics, such as

    flash_ptr++; // increment address by 1
    char temp2 = *flash_ptr ; //read second byte of Info D

    Furthermore, you can even treat it like an array (since arrays are basically just pointers to a contiguous memory location)

    char temp3 = flash_ptr[3];

    BTW, declaring a const pointer does NOT prevent you from modifying the memory; only the location of that initial pointer is constant. So the following code is legal:

    char* const flash_ptr = (char*) 0x1000;
    *flash_ptr = 'a'; 

    That is if you've enabled flash write.

    Hope that helps.

    Tony

  • Well I rewrote some of the code based on what you gave me, it works, but only when I put a breakpoint and step through the write loop (and I can see the memory being modified in the memory view). I'll post the read/write code my project uses below, I don't know if CCS is rewriting the flash memory when it reloads the program or something but I don't think it's the IDE interfering with it.

    unsigned int* passcode_ptr = (unsigned int*) 0x10BF;

     //Flash implementation of above function
     void setPasscode(int nPass[])
     {
         unsigned int i;
         

      //Flash_ptr = (char *) 0x1080;              // Initialize Flash pointer
      FCTL1 = FWKEY + ERASE;                    // Set Erase bit
      FCTL3 = FWKEY;                            // Clear Lock bit
      //*Flash_ptr = 0;                           // Dummy write to erase Flash segment
          *passcode_ptr = 0; //dummy write

      FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation

      for (i=0; i<=3; i++)
      {
        *passcode_ptr = nPass[i];                   // Write value to flash
        passcode_ptr--;
      }

      FCTL1 = FWKEY;                            // Clear WRT bit
      FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
     
      passcode_ptr = (unsigned int*) INFO_B0; //default values of passcode_ptr, INFO_B0 = 0x10BF
     
     }

    I have FCTL2 configured in GRACE and it is between the threshold frequencies just to let you know.

    Here is the read code:

     unsigned int* passcode_ptr = (unsigned int*) 0x10BF;

    int compareCodes_pt(int code1[], unsigned int *code2)
     {
         int i;
         for(i=0; i<=3; i++)
         {
             if(code1[i] != *code2)
                 return 0;
             code2--;
         }
         return 1;
     }

    It worked once, but I was stepping through the write process, do you see anything wrong? Thanks again, I've never worked with embedded flash memory before :/

    EDIT: As it turns out, my timer interrupt (set to run every 10ms to scan keypad) was interfering with the write, so I moved the interrupt enable command after the initial write command in main, appears to work now, for anyone else experiencing this problem, disable interrupts while writing (unless the write occurs during an interrupt). Thank you for your help in understanding pointers and writing to flash Tony!

  • Hi Don,

    When you address 0x10BF with an int pointer, you actually address both 0x10BF and 0x10C0, the latter of which is in Info A, since for MSP430 an integer/word is a 16-bits or 2-bytes. A better way to access Info B as integers would be to start at 0x1080, and then increment upward.

    Also, depending on your settings the IDE may erase the Info memory segments when you load your program (except Info A which is by default locked as it contains calibration data), so that could be why your data disappears afterwards. You can change it so that the debugger retains the contents in Info when you program the flash.

    Otherwise I think your code should work fine.

    Tony

**Attention** This is a public forum