How to access backup SRAM of STM32F4?

Datasheet of STM32F407 states that those MCUs have up to 4KB of backup SRAM. Is this part of SRAM being used in mbed? If not, how do we access it?

Thanks.

Hello Zhiyong,

The 4k backup SRAM is not used by Mbed OS.

The memory region can be accessed following guides from the STM32F407 reference manual. Specifically chapter 5.1.2 battery backup domain.

I modified the mbed-os-example-blinky a bit to show this in practice:

/* mbed Microcontroller Library
 * Copyright (c) 2019 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include "mbed.h"
#include "platform/mbed_thread.h"


// Blinking rate in milliseconds
#define BLINKING_RATE_MS                                                    500

void bkpsram_enable(void) {
    printf("Enabling Backup SRAM\n");

    /* Enable the power interface clock */
    printf("RCC->APB1ENR = 0x%08" PRIx32 "\n", RCC->APB1ENR);
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    printf("RCC->APB1ENR = 0x%08" PRIx32 "\n\n", RCC->APB1ENR);

    /* Set the DBP bit to enable access to the backup domain */
    printf("PWR->CR      = 0x%08" PRIx32 "\n", PWR->CR);
    PWR->CR |= PWR_CR_DBP;
    printf("PWR->CR      = 0x%08" PRIx32 "\n\n", PWR->CR);

    /* Enable the backup SRAM clock */
    printf("RCC->AHB1ENR = 0x%08" PRIx32 "\n", RCC->AHB1ENR);
    RCC->AHB1ENR |= RCC_AHB1ENR_BKPSRAMEN;
    printf("RCC->AHB1ENR = 0x%08" PRIx32 "\n\n", RCC->AHB1ENR);

    /* Enable backup regulator */
    printf("PWR->CSR     = 0x%08" PRIx32 "\n", PWR->CSR);
    PWR->CSR |= PWR_CSR_BRE;
    printf("PWR->CSR     = 0x%08" PRIx32 "\n", PWR->CSR);

    /* Wait for backup regulator to be ready  */
    while (!(PWR->CSR & (PWR_FLAG_BRR)));

    printf("Backup SRAM enabled\n");
}

void bkpsram_read(void) {
    int *i1 = (int*)BKPSRAM_BASE;
    int *i2 = i1 + 1;
    int *i3 = i1 + 2;

    printf("i1=%d\ni2=%d\ni3=%d\n", *i1, *i2, *i3);
}

void bkpsram_write(void) {
    int *i1 = (int*)BKPSRAM_BASE;
    int *i2 = i1 + 1;
    int *i3 = i1 + 2;

    *i1 = 1;
    *i2 = 2;
    *i3 = 3;
}

int main()
{
    // Initialise the digital pin LED1 as an output
    DigitalOut led(LED1);

    // Initialise and write ST backup SRAM
    bkpsram_enable();
    bkpsram_read();
    //bkpsram_write();
    //bkpsram_read();

    while (true) {
        led = !led;
        thread_sleep_for(BLINKING_RATE_MS);
    }
}

/*
Example stdout:
 Enabling Backup SRAM
 RCC->APB1ENR = 0x10040008
 RCC->APB1ENR = 0x10040008

 PWR->CR      = 0x0003c000
 PWR->CR      = 0x0003c100

 RCC->AHB1ENR = 0x0010000a
 RCC->AHB1ENR = 0x0014000a

 PWR->CSR     = 0x00034208
 PWR->CSR     = 0x00034208
 Backup SRAM enabled
 i1=1
 i2=2
 i3=3
 0
 1
 2
 3
 4
*/

Above code was tested with NUCLEO-F429ZI as I didn’t have F407 device close by. But to my understanding, the process should be the same for F407.

Best regards,
Jaakko, team Mbed

1 Like

I’m using two simple functions

uint32_t readBackupReg(uint32_t backup_register) {
    RTC_HandleTypeDef RtcHandle;
    RtcHandle.Instance = RTC;
    return HAL_RTCEx_BKUPRead(&RtcHandle, backup_register);
}

void writeBackupReg(uint32_t backup_register, uint32_t data) {
    RTC_HandleTypeDef RtcHandle;
    RtcHandle.Instance = RTC;
    HAL_PWR_EnableBkUpAccess();
    HAL_RTCEx_BKUPWrite(&RtcHandle, backup_register, data);
    HAL_PWR_DisableBkUpAccess();
}

For those who intend to use RTC backup registers and backup SRAM, please be aware that

HAL_PWR_DisableBkUpAccess();

also disables future access to RTC registers. As a result, set_time() will cause error then crash system. I briefly described the issue in another thread on this forum, the following thread on stackoverflow describes it more in detail.