STM32 Save data in RAM between reboots

procedures, notes, reminders
Post Reply
comarius
Posts: 14
Joined: Thu Nov 07, 2019 3:32 am

STM32 Save data in RAM between reboots

Post by comarius » Thu Jan 16, 2020 3:17 pm

To avoid wear-out of flash data can be saved gracefully in RAM area.
The data is preserved as long the CHIP is powered.


You have to know your MPU RAM size. Usually you can find this information
in the data sheet or using the STM32CubeMX tool for the MPU./MCU list.


Once you have the skeleton code generated (I am using STM303) you can open
the linker file.
We are interested at _estack and RAM entry in the MEMORY section.

Code: Select all

/* Highest address of the user mode stack */
_estack = 0x20010000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 512K
}
Let's have 2 K at the end of RAM saving data between HOT reboots (no power off).
Let's make changes

Code: Select all

_estack = ORIGIN(RAM) + LENGTH(RAM);
MY_SPACE = 2K;

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K-MY_SPACE
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 512K
}
Then down in sections

Code: Select all

/* Define output sections */
SECTIONS
{
   ram_user_start = ORIGIN(RAM)+LENGTH(RAM);
   ram_user_len  = MY_SPACE;

Now in the C code have a structure with things you want to save.

Code: Select all

typedef struct 
{
      uint32_t signature;
      uint32_t hangs;
      // other stuff
}MyStuff;
Now access from c the linker section ram_user_start

Code: Select all

extern uint32_t ram_user_start;  // inserted by linker in map

MyStuff* get_ram()
{
      MyStuff* p = (MyStuff*)&ram_user_start;
      return p;
}

Sample: save number of reboots due WD reset

Code: Select all

void main(void)
{
     //  ....
    if(__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET ||
       __HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)
    {
        __HAL_RCC_CLEAR_RESET_FLAGS();
         MyStuff*  ps = get_ram();
          if(ps->signature!=0XA5)
          {
               ps->signature=0XA5;
              ps->hangs=0;
          }else
              ++ps->hangs;
    }
}

Post Reply