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.

MSP430FR2311: Variable defined as PERSISTENT is read-only

Part Number: MSP430FR2311

Hi,

I am trying to make a variable persistent using the PERSISTENT pragma. The code is a copy of an example made by Andreas Dannenberg (posted somewhere on the TI forums):

//============================================================================
// Name        : #pragma PERSISTENT Test for C++
// Author      : Andreas Dannenberg
// Version     : 1.0
//============================================================================

#include "msp430.h"

// Declare a simple class that maintains a static counter variable. Note that
// only one copy of this variable is shared by all instances of this class.
class PersistentTest {
public:
    int getCounter() {
        return counter;
    }
    void setCounter(int newCounterValue) {
        counter = newCounterValue;
    }
    void incrementCounter() {
        counter++;
    }
private:
    static int counter;
};

// In C++ the counter needs to be explicitly defined/initialized. For data
// members this has to be done outside the class in the namespace scope. This
// is also where we are going to apply the PERSISTENT pragma.
#pragma PERSISTENT
int PersistentTest::counter = 0;

int main() {
    // Stop the MSP430's watchdog timer
    WDTCTL = WDTPW | WDTHOLD;

    // Create an instance of our test class
    PersistentTest persistentTest;

    // Call the member function to increment the class-internal counter
    persistentTest.incrementCounter();

    // Obtain a snapshot of the class-internal counter
    volatile int currentCounterValue = persistentTest.getCounter();

    // Set breakpoint here and use the debugger to look at the value of
    // 'currentCounterValue'. Then, reset the device and run and re-inspect.
    __no_operation();

    return 0;
}

I've created a blank project, uploaded this code, but the persistent variable won't change value. It'll stay at 0. The value cannot be changed with the debugger (program stopped at a breakpoint): it simple flips back to 0.

The .map file shows that the variable is located in the persistent section:

 output                                  attributes/
section   page    origin      length       input sections
--------  ----  ----------  ----------   ----------------
.TI.persistent 
*          0    0000f100    00000002     
                  0000f100    00000002     main.obj (.TI.persistent)

What could be the problem?

EDIT: After a power cycle (removed power for a few seconds) the example worked. However, I have a more complex program that still shows the same behavior. Clues are very welcome Slight smile

Thanks,

Justus

  • Additional info: the simple example .map file shows the persistent symbol in the GLOBAL SYMBOLS listing:

    GLOBAL SYMBOLS: SORTED BY Symbol Address 
    
    address   name                        
    -------   ----                        
    000000a0  __STACK_SIZE                
    .....removed lines.....                 
    00002360  _stack                      
    00002400  __STACK_END                 
    0000f100  _ZN14PersistentTest7counterE

    This is not the case with my other program (which does have variable in the.TI.persistent section, located also at 0000f100):

    SECTION ALLOCATION MAP
    
     output                                  attributes/
    section   page    origin      length       input sections
    --------  ----  ----------  ----------   ----------------
    .TI.persistent 
    *          0    0000f100    00000011     
                      0000f100    00000010     main.obj (.TI.persistent:_ZN29_INTERNAL_8_main_cpp_183a4ba47Globals6alarmsE$0)
                      0000f110    00000001     main.obj (.TI.persistent)
    
    ....lines removed....
    
    GLOBAL SYMBOLS: SORTED BY Symbol Address 
    
    address   name                                   
    -------   ----                                   
    000000a0  __STACK_SIZE   
    ....lines removed....
    00002360  _stack                                 
    00002400  __STACK_END                            
    0000f12e  __TI_Handler_Table_Base                
    0000f134  __TI_Handler_Table_Limit               
    
    

    Note that this program uses almost all FRAM in the MCU, and the optimization level is set to whole program optimization (4) with --opt_for_speed set to size (0).

  • At reset the FRAM is write-protected. To write to it you need to set SYSCFG0:PFWP=0 (then set it back to =1 when you're finished). [Ref User Guide (SLAU445I) Table 1-24]

    This is illustrated in example msp430fr231x_framwrite.c here:

    https://dev.ti.com/tirex/explore/node?node=A__AHbDS4Rv1nVVIcfPWJjnKg__msp430ware__IOGqZri__LATEST

**Attention** This is a public forum