Skip to main content
Visitor II
August 5, 2020
Solved

Memory/Instruction barriers before writing to the backup SRAM

  • August 5, 2020
  • 12 replies
  • 6169 views

The following code didn't worked because of a missing data barrier before writing to the backup SRAM:

HAL_PWR_EnableBkUpAccess();
std::copy(buffer, buffer + num_bytes, BaseAddress + address);
HAL_PWR_DisableBkUpAccess();

Adding a DSB, solved the issue for now.

HAL_PWR_EnableBkUpAccess();
__DSB();
std::copy(buffer, buffer + num_bytes, BaseAddress + address);
HAL_PWR_DisableBkUpAccess();

It is understandable, that the enable BkUp (which is setting a single bit) needs to be fully completed before writing the the actually memory addresses.

But for me it is not fully understandable, if a DMB would be enough (it also works) and if I need an additional ISB, so Enable and Disable don't happen just before the actual copy, like so:

HAL_PWR_EnableBkUpAccess();
__DSB();
std::copy(buffer, buffer + num_bytes, BaseAddress + address);
__ISB();
HAL_PWR_DisableBkUpAccess();

Can someone help me out here, what the correct way would be?

    This topic has been closed for replies.
    Best answer by waclawek.jan

    > how can I be sure the effect of enable is effective?

    It may not be sufficient, if APB1 is slow, or if there are busmaster (DMA) conflicts on APB1. See below.

    The H4 is very, VERY different in this - backup SRAM is there by default in Normal area which can reorder writes even if the area is not cached. The bus structure is different, too. Barriers may be necessary and also not sufficient; I am not interested in 'H4 to pay more than casual attention.

    In 'F4, writes never get reordered, not even in Normal area. The issue here is given by the relatively slow APB1 bus on which PWR sits, versus the relatively fast AHB1 bus on which BKPSRAM (and RCC with BDCR) sits. The same applies to all backup domain items.

    I've talked about it here already a couple of years ago, ST "discovered" it only recently (see the 'F407 erratum "Possible delay in backup domain protection disabling/enabling after programming the DBP bit"). Use the recommended workaround from there - for your case, only the readback is applicable (C, I don't ++):

    PWR->CR |= PWR_CR_DBP;
     (void)PWR->CR; // readback to ensure the bit is set before commencing the SRAM/RTC access, as PWR is on APB1 whereas RTC and SRAM are on AHB1

    There is no such issue in the other way round, i.e. after writing to BPKSRAM, there is no need for any delay before writing to PWR_CR.DBP.

    You may want to make sure the compiler won't reorder accesses, though (see volatile and sequence points; again, I don't ++).

    JW

    12 replies

    Super User
    August 11, 2020

    > speculative execution... but it ended badly

    You are using it every day. F7/H7 does it too. There is no more Moore.

    JW

    Super User
    August 19, 2024

    @nickbeth,

    In context of 'F4 (or other STM32 with similarly connected PWR and BKPSRAM), yes, you may need to have a delay (as I wrote above, the barrier instruction there functions only as a delay, and it may or may not be sufficient depending on the particular APB divider and maybe also some other circumstances) after disabling backup domain access in PWR, if you anticipate rouge accesses to BKPSRAM may follow immediately after that disable.

    But usually you write your code so that such rouge accesses are possible only through some inadvertent action later in the code, i.e. that there's enough delay in the "proper" code following the PWR_CR.DBP clear.

    JW