Jump to content
jackak

Persistent Variables on MSP430FR5994

Recommended Posts

Hi folks!  I am working on a project using an MSP430FR5994 through Energia 1.8.11E23 on Linux.  As part of that project I would like to persist some variables, i.e. they are set once when the code is flashed and then if updated will retain the updated value upon power cycle, reset, etc.  A simple counter example code I am using to test this is shown below.  The desired behaviour is that the counter starts at 5 and then continues, and does not reset back to five even if the MSP is power cycled or reset.

I have tried the existing undocumented PLACE_IN_FRAM (a macro for __attribute__((section(".text;")))), with both the original and the elf-GCC compilers.  This sets the variable, but does not seem to allow it to be altered.  I note that the section that this places the variable in, .text, is defined as read only in the linker scripts for both compilers.  The original places the .text section it in the rom (rx) region while the elf compiler places it in the text (rx) region.  This confuses me, as existing forum threads (e.g. https://forum.43oh.com/topic/13099-mspflash-do-not-work-on-msp4305969/?do=findComment&comment=80848) seemed to imply that this would create a persitent, read/writeable variable.  The comment accompanying the macro in pins_energia.h also implies the same.

I then tried using  __attribute__((persistent)) with the new elf-GCC compiler during my variable declaraion.  Upon compile, this gave the following warning "variable 'FRAM_count' was declared persistent and should be explicitly initialized [-Wattributes]".  I was unable to resolve this, despite (by my understanding) explictly declaring the variable in a variety of ways.  Unlike the previous approach, this did allow the variable to be written, with the count incrementing.  However, upon power cycling the count reset to five and did not persist the variable.

The code I used to test the above (and other) approaches is shown below:

//uint8_t FRAM_count PLACE_IN_FRAM = 5;  // Doesn't increment, seems to be read only after init

unsigned long int FRAM_count __attribute__((persistent)) = { 5 };  // Doesn't persist, 
// Gives compiler warning: variable 'FRAM_count' was declared persistent and should be explicitly initialized [-Wattributes]

//uint8_t FRAM_count __attribute__((section(".persistent"))) = { 5 }; // Doesn't increment

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print("Initial value of FRAM_count is: ");
  Serial.println(FRAM_count, DEC);
  Serial.println("Setup Completed");
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(FRAM_count, DEC);
  FRAM_count++;
  delay(1000);
}

Any suggestions or support that those of you more familiar with the Energia/MSP framework could give would be greatly appreciated!  I have spent a few days on this now and have checked these and other forums but have thus far had no success.

 

Share this post


Link to post
Share on other sites

Hi,

It seems there is a bug using the "persistent" attribute in C++. Internally, the compiler validates the attribute and emits that warning before the initializer has been parsed.

The attribute works fine in a C program.

As a work-around I would suggest explicitly putting the variable in the ".persistent" section, this has the same effect as the "persistent" attribute.

unsigned long int __attribute__((section(".persistent"))) FRAM_count = 5;

Apologies that this bug caused confusion!

Regards,

Jozef

Share this post


Link to post
Share on other sites
On 9/11/2020 at 11:32 AM, JozefL said:

Hi,

It seems there is a bug using the "persistent" attribute in C++. Internally, the compiler validates the attribute and emits that warning before the initializer has been parsed.

The attribute works fine in a C program.

As a work-around I would suggest explicitly putting the variable in the ".persistent" section, this has the same effect as the "persistent" attribute.


unsigned long int __attribute__((section(".persistent"))) FRAM_count = 5;

Apologies that this bug caused confusion!

Regards,

Jozef

Hi Jozef,

Thanks for that info, however I tried your recommendation and found that the variable, once set at 5, could not then be changed by other lines in the code (i.e. FRAM_count++) and instead would remain at five.  This is similar to the behaviour I observed from the energia-defined PLACE_IN_FRAM, despite the fact that the data memory region the .persistent section is in is rwx.  Is this the intended behaviour and am I simply misunderstanding the persistent attribute, or are there other factors at play here?  I wondered if it could be an MPU issue, but my understanding is that the MPU is disabled by default?  

Thanks again for your suggestion!

Share this post


Link to post
Share on other sites
4 hours ago, jackak said:

Hi Jozef,

Thanks for that info, however I tried your recommendation and found that the variable, once set at 5, could not then be changed by other lines in the code (i.e. FRAM_count++) and instead would remain at five.  This is similar to the behaviour I observed from the energia-defined PLACE_IN_FRAM, despite the fact that the data memory region the .persistent section is in is rwx.  Is this the intended behaviour and am I simply misunderstanding the persistent attribute, or are there other factors at play here?  I wondered if it could be an MPU issue, but my understanding is that the MPU is disabled by default?  

Thanks again for your suggestion!

Yes, you shouldn't need to change any settings to be able to read and write from the main FRAM block.

I'm able to observe a persistent variable being incremented with the following code on the FR5994

#include <stdio.h>
#include <msp430.h>

unsigned long __attribute__((section(".persistent"))) persist = 5;

int main (void)
{
  WDTCTL = WDTPW | WDTHOLD;
  while (1)
  {
    persist++;
    printf ("persist %ld\n", persist);
    for (int i = 0; i < 1000; i++);
  }
  return 0;
}

I don't know what setup Energia does by default, but you should check that at least the watchdog is disabled, if it fires before you get to the modification of the persistent variable, then it will just stay at 5.

There's plenty of posts about writing to FRAM on the TI E2E forums, you could check there if you continue to have problems. Particularly check out the code examples included in this thread https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/911028?tisearch=e2e-sitesearch&keymatch=msp430%20fram%20write

Regards,

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...