STM32 gotchas
83.Cannot access BKPSRAM in CubeProgrammer (unless register values are manipulated)

This article is a summary of a related discussion on STM32 Forum. Thanks to ST employee with nick Mike_ST for the support!

The backup SRAM (BKPSRAM) is a portion of few kilobytes of static RAM, which is supplied from the VBAT power domain, thus retains its content even if VDD is completely removed. It is present only in some STM32 families ('F2, 'F4, 'F7, and in 'H7, where it is confusingly called BKPRAM).

As with other circuits in the VBAT (backup) domain such as RTC (with backup registers and tamper protection) and LSE, write access to BKPSRAM is protected by PWR_CR.DBP bit. However, the backup domain reset through setting RCC_BDCR.BDRST does not affect BKPSRAM content, and after powering down and up the backup domain (by removing both VDD and VBAT) the BKPSRAM content is random.

BKPSRAM shares also some characteristics with FLASH - it is essentially non-volatile (provided VBAT is present and the BKPSRAM-associated low-power regulator is enabled), it is protected by RDP in the same way as FLASH is, it's even cleared when RDP changes from Level 1 to Level 0.

It might be a reasonable expectation, then, that programming tools - such as ST-supplied CubeProgrammer - support writing and reading of BKPSRAM in the same way as writing and reading FLASH, for purposes of both development and production. Turns out, this is not entirely the case.

While CubeProgrammer allows to read and write any area of the memory space of target STM32, thus including BKPSRAM; it also maintains all the registers in its reset state. As access to BKPSRAM is subject to enabling its APB clock (by setting RCC_AHB1ENR.BKPSRAMEN, which is zero after reset), to be able to read BKPSRAM in CubeProgrammer, this bit has to be set "manually". As said, CubeProgrammer allows to access any address in memory space, this includes also RCC registers, so this can be accomplished for example for STM32F405/407 by selecting an area starting e.g. at 0x4002'3800 (this is starting address of the RCC registers area), selecting the word at 0x4002'3830 which is RCC_AHB1ENR (this has default value of 0x0010'0000 as CCM RAM's clock is enabled after reset), and writing the value 0x0014'0000 into it. After this, selecting the BKPSRAM area at 0x4002'4000 displays the BKPSRAM content.

Should we want to write to BKPSRAM, we would need to enable PWR clock first (by setting RCC_APB1ENR.PWREN, i.e. writing 0x1000'0000 into 0x4002'3840), then enable backup domain write by setting PWR_CR.DBP (writing 0x0000'4100 into 0x4000'7000), and to retain written values in VBAT mode, the BKPSRAM's low-power regulator has to be enabled by setting PWR_CSR.BRE (writing 0x0000'0200 into 0x4000'7004).

For other STM32 models, the particular register addresses and values may be different, but the principle remains.