cancel
Showing results for 
Search instead for 
Did you mean: 

AXI SRAM losing last few writes across reset

CHead
Associate III

it seems that a write to AXI SRAM very shortly before a system reset (via AIRCR) gets lost. I wrote a very short block of code that simply reads a word from 0x24000000, increments it, writes it back, and resets the processor. I can see that the value is not changing. Using a debug tool, I can see that, if I manually modify the contents of memory, the register used for the increment changes accordingly. Also, if I use the debug tool to display that memory location after the code should have written it, it shows the new value. However, if I let the code write back the new value, then reset the processor, the memory reverts to its old value after the reset (as shown both by reading the memory directly or by displaying the register).

I saw this note in the reference manual: “When a half word is written to an internal SRAM and a reset occurs, this half word is not really written to the SRAM after reset. This due to the ECC behavior.�? However, this does not apply: I am doing full-word-size reads and writes. It also can’t be a cache issue because I have the caches turned off. I have set PWR_CR3 appropriately (without which SRAM is apparently read-only), and I have set AXI_TARG7_FN_MOD.READ_ISS_OVERRIDE=1 due to the erratum. I have the necessary DSB before writing to AIRCR. I also tried introducing an ISB as well. I also tried (as recommended in the Cortex-M programming guide to barrier instructions, AN321) adding a dummy read from the AXI SRAM after the write, including with a DSB+ISB both before and after the dummy read. All to no avail.

Everything seems to work just fine during normal operation; it’s only after reset that this problem shows up. This problem doesn’t seem to happen if I use the DTCM or the AHB SRAM, only the AXI SRAM.

Any ideas?

1 ACCEPTED SOLUTION

Accepted Solutions

I don't know if you all follow also the FAQ section, I've just stumbled upon this interesting FAQ (being linked to from another thread, this time backup-SRAM-related, to which this issue pertains, too):

https://community.st.com/s/article/FAQ-STM32H7-SRAM-Backup-SRAM-content-is-not-preserved-after-reset

JW

@Community member​ , @Pavel A.​ , @Community member​ , @Piranha​ , @CHead​ , @Harrold​ , @ETywo.1​ , @Kilian Nötzold​ , @ZYubi​ 

View solution in original post

12 REPLIES 12

...

 SCB_CleanDCache();

 NVIC_SystemReset();

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

In my real code, I *do* clean the D-cache before resetting. In my test code, I don’t even enable the caches.

Would writing more words make any difference?

JW

In a way, yes. It seems I misunderstood the sentence “When a half word is written to an internal SRAM and a reset occurs, this half word is not really written to the SRAM after reset. This due to the ECC behavior.�? I interpreted “half word�? using the standard ARM definition (i.e. 16 bits), but it seems that ST actually meant any size less than a full ECC word (so for the AXI SRAM, this includes 32 bits). If all writes are performed at 64-bit size, this problem doesn’t happen.

It’s rather impractical to always make sure that every write to memory areas I want to persist across a reboot is always 64 bits wide. However, it seems that there are a couple of workarounds that seem to work. One is to write a byte elsewhere, far away, before resetting; this seems to flush out any sub-64-bit data accumulated in whatever store buffer is equipped. The other is to copy all the data I care about back on top of itself using only 64-bit accesses (which obviously doesn’t modify the data at all, but does appear to flush out whatever store buffer is causing the problem).

Overnight test pending to see whether it actually solves it fairly reliably…

Huh, this is an interesting piece of information. And there's some logic in it, too.

ST might want to start to be more precise in its documentation. Btw., that sentence appeared only in the latest version of the RM...

JW

CHead
Associate III

Overnight test ran ~17,000 resets and rewriting the data that used to get corrupted at 64-bit size resulted in it not getting corrupted.

Thank you for posting this information. I experienced exactly the same behavior on my STM32H743 MCU where my application tried to communicate with my bootloader. The application writes data to address 0x20000000 (DTCM RAM) just before calling HAL_NVIC_SystemReset(). Using the debugger, the memory looks fine before the reset, but after resetting, the memory contained the old value again.

It was solved (thanks to your posting) by adding the following line of code:

*((volatile uint64_t *) 0x20000000) = *((volatile uint64_t *) 0x20000000);

You wrote the problem doesn’t seem to happen using DTCM, but in my case I'm using DTCM. Maybe it depends on the MCU type.

Piranha
Chief II

This is really interesting. Here is a question to both - @CHead​ and @Harrold​.

> Using the debugger, the memory looks fine before the reset, but after resetting, the memory contained the old value again.

Is that memory marked as volatile? Because, if it isn't, the compiler is not required to store it immediately. The store can be placed even after NVIC_SystemReset(), which would produce exactly these results.

In my case, yes. When I said I used the debugger, I mean I printed the memory by address, not the variable (which the debugger could have interpreted as a request to print a register instead).