FAQ: STM32H7 SRAM/Backup SRAM content is not preserved after reset
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2020-10-16 5:43 AM
Backup SRAM or normal SRAM content is not preserved after reset or wake up from standby. After reset last few bytes written are not kept. What is the problem?This issue appears on STM32H7 devices and is caused by the ECC (Error Code Correction) which is computed for each word of SRAM (64-bit for AXI SRAM, 32-bit for other SRAMs, including backup SRAM).
All "word-aligned" write accesses are directly written to the SRAM. Word-aligned access is when whole SRAM word is written to aligned address:
To flush this cache after "word-unaligned" access, there are two options:
The code for flushing the ECC can look like this:
Please note this issue only affects data retention after reset or exit from standby mode (which acts as reset). It doesn't affect coherency between core and DMA, since this one word cache is a part of SRAM.
All "word-aligned" write accesses are directly written to the SRAM. Word-aligned access is when whole SRAM word is written to aligned address:
- For AXI SRAM, this is 64-bit write to aligned address which is multiply of 8
- For other SRAMs this is 32-bit write to aligned address which is multiply of 4
To flush this cache after "word-unaligned" access, there are two options:
- perform other "unaligned" access to other SRAM word
- perform read and write aligned operation on the same SRAM word as the last access
The code for flushing the ECC can look like this:
void FlushECC(void *ptr, int bytes){ uint32_t addr = (uint32_t)ptr; /* Check if accessing AXI SRAM => 64-bit words*/ if(addr >= 0x24000000 && addr < 0x24080000){ volatile uint64_t temp; volatile uint64_t* flush_ptr = (uint64_t*) (addr & 0xFFFFFFF8); uint64_t *end_ptr = (uint64_t*) ((addr+bytes) & 0xFFFFFFF8); do{ temp = *flush_ptr; *flush_ptr = temp; flush_ptr++; }while(flush_ptr != end_ptr); } /* Otherwise 32-bit words */ else { volatile uint32_t temp; volatile uint32_t* flush_ptr = (uint32_t*) (addr & 0xFFFFFFFC); uint32_t *end_ptr = (uint32_t*) ((addr+bytes) & 0xFFFFFFFC); do{ temp = *flush_ptr; *flush_ptr = temp; flush_ptr++; }while(flush_ptr != end_ptr); } }This can be useful e.g. for flushing whole C structure, when we are not sure which variable was written last.
Please note this issue only affects data retention after reset or exit from standby mode (which acts as reset). It doesn't affect coherency between core and DMA, since this one word cache is a part of SRAM.
This discussion is locked. Please start a new topic to ask your question.
0 REPLIES 0
