Skip to main content
maborbaa
Associate II
October 21, 2025
Solved

Persisting data in BKPSRAM with STM32WBA

  • October 21, 2025
  • 4 replies
  • 731 views

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

Best answer by mbrossett

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

 

 

4 replies

Associate II
October 21, 2025

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. 

 

Associate II
October 21, 2025

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

maborbaa
maborbaaAuthor
Associate II
October 23, 2025

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 ();

 

Associate II
October 23, 2025

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.

Associate II
October 24, 2025

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?

maborbaa
maborbaaAuthor
Associate II
October 24, 2025

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

Associate II
October 24, 2025

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

mbrossettBest answer
Associate II
October 24, 2025

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

 

 

maborbaa
maborbaaAuthor
Associate II
October 24, 2025

I understand.