cancel
Showing results for 
Search instead for 
Did you mean: 

Persisting data in BKPSRAM with STM32WBA

maborbaa
Associate II

Edited by a ST moderator to follow the community rules especially for code sharing. So please use </> to share your code

 

Hello,

I am using the STM32WBA, and I am interested in persisting data to start after waking up from standby mode.
I am unable to keep the data in memory. Here is how I am configuring the linker script and main.c.
Can you please help me with how to keep the data when waking up? I am configuring a pot for wakeup GPIO_PIN_13.
My goal is for the MCU to wake up, perform some actions, and go back to sleep repeatedly.

STM32WBA55CGUX_FLASH.ld

MEMORY
{
  RAM (xrw)   : ORIGIN = 0x20000000, LENGTH = 128K
  FLASH (rx)    : ORIGIN = 0x8000000,  LENGTH = 1024K
  BKPSRAM (xrw) : ORIGIN = 0x40024000, LENGTH = 2K
}

## after .bss:  ##

.bss_bkpsram (NOLOAD) :
{
   . = ALIGN(4);
   KEEP(*(.bss_bkpsram)) 
   . = ALIGN(4);
} > BKPSRAM

main.c

typedef struct
{
  uint32_t magic_number;
  uint16_t device_id;
} PersistentState_t;


__attribute__((section(".bss_bkpsram")))   volatile PersistentState_t g_persistent_state;

 __HAL_RCC_PWR_CLK_ENABLE();
 HAL_PWR_EnableBkUpAccess ();

if (__HAL_PWR_GET_FLAG(PWR_FLAG_SBF) != RESET)
{
        g_persistent_state.device_id++;
}
else
{
        g_persistent_state.magic_number = 0xCAFEFEED;
        g_persistent_state.device_id = 0x0001;
}

__HAL_PWR_CLEAR_FLAG(PWR_WAKEUP_FLAG2); 
HAL_PWREx_EnableStandbyIORetention (PWR_GPIO_C, GPIO_PIN_13);
HAL_PWR_EnableWakeUpPin (PWR_WAKEUP_PIN2_HIGH_1);
HAL_PWR_EnterSTANDBYMode ();

Best regards

1 ACCEPTED SOLUTION

Accepted Solutions

Your memory map is showing g_persistent_state is being placed on the stack. Make sure it is declared globally. 

View solution in original post

11 REPLIES 11
mbrossett
Associate III

The STM32WBA doesn’t appear to have ram in the backup domain like some other STM32 chips. However, SRAM1 and SRAM2 can have retention enabled in standby using theses functions…

 HAL_PWREx_EnableSRAM1ContentStandbyRetention()

HAL_PWREx_EnableSRAM2ContentStandbyRetention()

 

You will need to change the BKPSRAM address in your linker script as the address you have used is in the nonsecure peripheral region. Otherwise your linker script looks ok to me. 

 

mbrossett
Associate III

To use SRAM2 as standby ram use address 0x2007 0000 in your linker script. 

Hi @mbrossett , thanks for getting back to me.

I coded it as you suggested, but the data doesn't persist when I wake up.

MEMORY
{
  RAM	(xrw)  : ORIGIN = 0x20000000,  LENGTH = 64K
  FLASH (rx)   : ORIGIN = 0x8000000,   LENGTH = 992K 
  SRAM2	(xrw)  : ORIGIN = 0x20010000,  LENGTH = 64K  
}

...

      .bss_sram2 (NOLOAD) :
	{
	  . = ALIGN(4);
	  KEEP(*(.bss_sram2)) 
	  . = ALIGN(4);
	} > SRAM2


I used 0x2001 according to the RM0493: 0x2001 0000 - 0x2001 FFFF64 K(4)SRAM2

main.c

typedef struct
{
  uint32_t magic_number;
  uint16_t device_id;
} PersistentState_t;

#define BKPSRAM_CHECK_SIGNATURE 0xCAFEBABE

__attribute__((section(".bss_sram2")))  volatile PersistentState_t g_persistent_state;

__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWR_EnableBkUpAccess ();

GPIO_InitTypeDef GPIO_InitStruct = { 0 };
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; 
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init (GPIOC, &GPIO_InitStruct);

if (g_persistent_state.magic_number == 0xCAFEFEED)
{
      // "WARM BOOT"
      g_persistent_state.device_id++;
}
else
{
      // "COLD BOOT"
      g_persistent_state.magic_number = 0xCAFEFEED;
      g_persistent_state.device_id = 1;
}

__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SBF);
__HAL_PWR_CLEAR_FLAG(PWR_WAKEUP_FLAG2);
HAL_PWREx_EnableStandbyIORetention (PWR_GPIO_C, GPIO_PIN_13);
HAL_PWR_EnableWakeUpPin (PWR_WAKEUP_PIN2_HIGH_1);

HAL_PWREx_EnableSRAM2ContentStandbyRetention(PWR_SRAM2_FULL_STANDBY_RETENTION);

HAL_PWR_EnterSTANDBYMode ();

 

I may not be understanding Table 89 correctly, but it appears that the SRAM cannot be retained in Standby mode with wakeup capability.

 

You could use reset to exit Standby mode, in which case you need to check the SRAM2_RST option bytes (not sure of the default setting) to make sure the SRAM doesn't get erased during the reset.

mbrossett
Associate III

Ah duh never mind. I understand the table now. 

Well it’s not obvious what the problem is. Can you attach the .map file?

Are you testing this with a debug probe attached or not?

I’m testing with the debug probe connected. Honestly, I’m not sure how else I could do it.
I use the IDE’s debugging features.

I renamed the file to .txt

Your memory map is showing g_persistent_state is being placed on the stack. Make sure it is declared globally. 

i changed it in the linker

 SRAM2		(xrw)	: ORIGIN = 	0x20010000, 	LENGTH = 64K  

      .sram2_persistent (NOLOAD) :
	{
	  . = ALIGN(4);
	  KEEP(*(.sram2_persistent))
	  KEEP(*(.sram2_persistent*)) 
	  . = ALIGN(4);
	} > SRAM2

main.c
__attribute__((section(".sram2_persistent")))  volatile PersistentState_t g_persistent_state;

.map
image.png

The data was stored, Thank you 

Why did it place what I configured earlier in SRAM1 instead of SRAM2, as I defined?




mbrossett
Associate III

Glad it is working now. Your linker script has the bss section defined as *(.bss*). The wildcard right after the bss is what caused the .bss_sram2 to be placed in the bss section instead of SRAM2. Changing the name of the section fixed it. I didn't catch that after the first look of the map file and was thinking this section was defined as *(.bss.*) in the linker script which wouldn't have picked up your previously named section.

mbrossett_1-1761323882729.png