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.

MSP430FR2433: Saving Data to INFOA Memory

Part Number: MSP430FR2433

Dear TI,

I have been playing around with the MSP430FR2433 Launchpad BlinkLED project to understand better how I can save data to non-volatile FRAM memory.  Note, I've been through lots of documentation and posts including SLAA628 FRAM Best Practices and have seen code examples about how to use the PERSISTENT and NOINIT pragmas etc.  

I want to use the PERSISTENT pragma with the LOCATION pragma to store some 1 time initialized data (at program time) in the information memory space.  Documentation does not explicitly state this can be done but it's close to working.  I've notice that the linker does put the variable at the right location, and it is initialized as expected, BUT I don't seem to be able to update it.  When I put the variable in with the program memory things work as expected.  Maybe I need to do something more with the SYSCFG0 register to update information memory?  

#pragma PERSISTENT(testVar)
#pragma location=0x1800                           // If I comment this out, then things work as expected except the variable is not in the information memory segment where I want it.
unsigned long testVar = 0x5544;

SYSCFG0 = FRWPPW | DFWP; // Program FRAM write enable
testVar++; // Record the port event in FRAM
SYSCFG0 = FRWPPW | PFWP | DFWP; // Program FRAM write protected (not writable)

Thanks,

Brett

  • I realize I'm going to need to use NOINIT with LOCATION since I want what was there to persist over a firmware upgrade

  • Hi Brett,

    See the attached example code.

    Let me know if you still have questions.

    #include <msp430.h> 
    #include <stdint.h>
    
    /*
     * Notes: By default both data and program FRAM memory is enabled and must be
     * disabled in order to write to these sections.
     * For more information on this topic see section 5.12.22
     * https://www.ti.com/lit/ug/slau132v/slau132v.pdf
     *
     * Noinit and persistent variables behave identically with the exception of
     * whether or not they are initialized at load time.
     * The NOINIT pragma may be used only with uninitialized variables. It
     * prevents such variables from being set to 0 during a reset.
     * It may be used in conjunction with the LOCATION pragma to map variables
     * to special memory locations, like memory-mapped registers, without
     * generating unwanted writes.
     * The PERSISTENT pragma may be used only with statically-initialized variables.
     * It prevents such variables from being initialized during a reset.
     * Persistent variables disable startup initialization; they are given an
     * initial value when the code is loaded, but are never again initialized.
     * By default, noinit or persistent variables are placed in sections
     * named .TI.noinit and .TI.persistent, respectively. The location of these
     * sections is controlled by the linker command file. Typically .TI.persistent
     * sections are placed in FRAM for devices that support FRAM and .TI.noinit sections
     * are placed in RAM.
     */
    /*
     * Some easy to use #defines
     */
    #define DISABLE_PF_WRITE_PROTECT        SYSCFG0 = FRWPPW | DFWP
    #define DISABLE_DF_WRITE_PROTECT        SYSCFG0 = FRWPPW | PFWP
    #define DISABLE_PF_DF_WRITE_PROTECT     SYSCFG0 = FRWPPW
    #define DISABLE_ALL_WRITE_PROTECT       SYSCFG0 = FRWPPW
    
    #define ENABLE_PF_WRITE_PROTECT         SYSCFG0 = FRWPPW | PFWP
    #define ENABLE_DF_WRITE_PROTECT         SYSCFG0 = FRWPPW | DFWP
    #define ENABLE_PF_DF_WRITE_PROTECT      SYSCFG0 = FRWPPW | PFWP | DFWP
    #define ENABLE_ALL_WRITE_PROTECT        SYSCFG0 = FRWPPW | PFWP | DFWP
    
    /*
     * Example
     * Declare variable 'peanut' persistent in Info memory at location 0x1800.
     * (initialize only once at load time = 0)
     *
     */
    #pragma PERSISTENT(peanut)
    #pragma LOCATION(peanut, 0x1800)
    uint16_t peanut = 0;
    
    /*
     * Example
     * Declare variable 'peach' persistent in Program memory at location 0xE000.
     * (initialize only once at load time = 0x1234)
     *
     */
    #pragma PERSISTENT(peach)
    #pragma LOCATION(peach, 0xE002)
    uint16_t peach = 0x1234;
    
    
    /*
     * Example
     * Declare variable 'apple, compiler will place automatically
     * (initialize only once at load time = 0x55AA)
     */
    #pragma PERSISTENT(apple)
    uint16_t apple = 0x55AA;
    
    /*
     * Example
     * Declare variable 'walnut' noinit in Info memory at location 0x1802.
     * (is not initialized at reset)
     *
     */
    #pragma NOINIT(walnut)
    #pragma LOCATION(walnut, 0x1802)
    uint16_t walnut;
    
    uint16_t SYSCFG0_copy;
    
    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    
    	SYSCFG0_copy = SYSCFG0 & (PFWP | DFWP);     // let's first confirm FRAM protection is on by default
    
    	peanut = 1;                                 // won't work because DFWP is enabled by default
    
    	DISABLE_DF_WRITE_PROTECT;					// so must first disable DFWP (DATA FRAM WRITE PROTECT)
    
    	peanut = 1;                                 // this time it worked
    
    	walnut = 2;                                 // verify we can change walnut
    
    	apple = 0x55AA;                             // won't work because PFWP is enabled by default
    
    	DISABLE_PF_WRITE_PROTECT;					// must first disable PFWP (PROGRAM FRAM WRITE PROTECT)
    
    	apple = 0xAA55;                            // this time it worked
    	
    	peach = 0;                                 // verify we can change peach
    
    	ENABLE_ALL_WRITE_PROTECT;                 // Don't forget to protect when done.
    
    	while(1);
    
    }
    

  • Thanks Dennis!  Those are good examples.  I'm not sure why I didn't run into them.  I actually did discover my issue, which I hypothesized but didn't know why at the time- that there is a difference between FRAM program memory writes and FRAM data (info) memory writes.  My code above does has the write protect bit set for the data memory.  I found another post that discussed how to modify the .cmd file so that NOINIT is in FRAM.  Anyway, it seems to be working as expected.  It was a bit confusing that INFO memory is also referred to as FRAM data memory.  Thanks again, Brett.

  • Excellent!  Glad to help.

**Attention** This is a public forum