Battery backed NV RAM

Status
Not open for further replies.
Hello,

Using the Teensy 3.5.

We're working on a sequencing system that requires us to pick up the sequence after a power failure.
This means we need to make a note of the current sequence number (small amount of data) somewhere at least every 15 seconds but worse case every sec. That's a lot of writing which is not suitable for EEPROM or SD Cards.

NVSRAM seems to be the best bet.

We're looking at a system lifetime of 5 to 10 years so although the system will be powered 99.99% of the time, the battery obviously has to remained charged for when the power does fail.

Just wanted some views on what others had used with the Teensy to achieve this type of goal.

Many thanks
Gary
 
Teensy 3.5 (and all 3.x boards) have a small 32 byte memory located at 0x4003E000, which stays alive if you connect a 3V coin cell to the VBAT pin. The startup code uses the last 4 bytes as part of its RTC initialization process. You can use the other 28 bytes for storing your sequence number or other frequently changed data. If you *really* want all 32 bytes, you could also edit the startup code.

You can make use of it like this:

#define NVRAM_INTEGER (*(uint32_t *)0x4003E000)

Then just read or write NVRAM_INTEGER. It's RAM so you can write as often as you like. If you're concerned about the compiler actually performing your writes immediately, adding "volatile" to the definition might be a good idea.
 
Cool. I did this and it works with 3V cell across GND<>VBat across unplugging - survives reset without battery.

As used I pulled the extra '*' from NVRAM_INTEGER in post #2, but just set up a pointer to use like this (avoiding the 8th uint32_t the RTC code uses):
Code:
#define NVRAM_INTEGER ((uint32_t *)0x4003E000)
volatile uint32_t *NVR_8 = NVRAM_INTEGER; // (uint32_t *) 0x4003E000;

void setup() {
  Serial.begin(57600);
  for ( int ii = 0; ii < 7; ii++ ) {
    Serial.println( NVR_8[ii] );
    NVR_8[ii] += ii*ii;
  }
}
 
Maybe my 'C' is poor - or maybe I just like the ARRAY[] indexing method - but I can't get the compiler to use the provided definition with the extra *
#define NVRAM_INTEGER (*(uint32_t *)0x4003E000)
to access the way I would see it used.

Code:
#define NVRAM_UINT32 ((uint32_t *)0x4003E000)

void setup() {
  Serial.begin(57600);
  for ( int ii = 0; ii < 7; ii++ ) {
    Serial.println( NVRAM_UINT32[ii] );
    NVRAM_UINT32[ii] += ii*ii;
  }
}

And that definition allows me to have 14 uint16_t's instead:
Code:
#define NVRAM_UINT32 ((uint32_t *)0x4003E000)
#define NVRAM_UINT16 ((uint16_t *)NVRAM_UINT32)

void setup() {
  Serial.begin(57600);
  for ( int ii = 0; ii < 14; ii++ ) {
    Serial.println( NVRAM_UINT16[ii] );
    NVRAM_UINT16[ii] += ii*ii;
  }
 
Teensy 3.5 (and all 3.x boards) have a small 32 byte memory located at 0x4003E000, which stays alive if you connect a 3V coin cell to the VBAT pin. The startup code uses the last 4 bytes as part of its RTC initialization process. You can use the other 28 bytes for storing your sequence number or other frequently changed data. If you *really* want all 32 bytes, you could also edit the startup code.

You can make use of it like this:

#define NVRAM_INTEGER (*(uint32_t *)0x4003E000)

Then just read or write NVRAM_INTEGER. It's RAM so you can write as often as you like. If you're concerned about the compiler actually performing your writes immediately, adding "volatile" to the definition might be a good idea.

Hi Paul,

This is REALLY useful - thanks. 28 bytes will be plenty for what we need. I note your recommended for the volatile. I just wondered if there is any chance of data corruption of half written data if say the power goes off during the writing of the 28 bytes. I suppose we could as a checksum as one of the end bytes so when reading the data on power restore we can be sure of clean data. Thoughts?

Many thanks
Gary
 
or write 2 vars with crc, upon reboot the one with valid crc will be taken

write first volatile A with crc
write second volatile B with crc

A is the main one, if crc fails it copies last valid from B, which wasnt written to as shutdown happened in A
 
Status
Not open for further replies.
Back
Top