Stm32 Problem with reading from Flash memory (incorrect data)

131 views Asked by At

I am working with STM32U575ZIt6 micro and I have a problem with reading data from Flash (one of the last pages) to RAM. Basically what happens is when i execute the code, the checksum of the data read is not matching the one i expect and that is because the data copied from flash to ram is missing some parts. If i execute the same code with the debugger, doing a step by step reading, the data is copied sucessfully and the checksum matches. My thought was that there was some timing problem so i tried adding some delay in the read function but that didnt work. Another thing i noticed is that adding code after the read function and the checksum calculation has an effect on the data read. Any clue what is the problem? Thanks for any answers

This is the function i am using to read data stored (correctly) in Flash

1 Read(BACKUP, (void*)&Regs, sizeof(fram_registers));
2 void Read(uint32_t data_address, uint32_t *data, uint16 len)
3 {
4   if ( len != 0 ) 
5   {
6        len/=4;
7
8        while(len--)
9        {
10            *data = *(__IO uint32_t *)data_address;
11            data_address += 4;
12            data++;
13        }
14   } 
15 }

This is data stored in backup enter image description here

This is what i get enter image description here

EDIT: I have tried the suggestions in the comments but nothing worked. I add some more information that may help. So this is the part of code that i am having trouble with:

16          Read(BACKUP, (void*)&Regs, sizeof(fram_registers));//the function is the same described before
                        
17          checksum = Adler32((const uint8*)&Regs, sizeof(fram_registers) - 4); //the last 4 bytes contain the checksum saved in backup
18          if(checksum != Regs.Cksm) {
19              //checksum = Adler32((const uint8*)&Regs, sizeof(fram_registers) - 4);

20          }

0x080fc000 is the address of BACKUP 0x20004b90 is the address of Regs

When i get to line 16 and step over with jlink this is what i get enter image description here

Rerunning the code, when i get to line 16 and step in the function and cycle trought lines 4 to 15 step by step i get the correct outcome: https://wetransfer.com/downloads/f32dfc6bdfb5819e222220ca7914ddee20240329073959/20f2d8 (i stopped the video just after reading the bytes that were read wrong before, but going on the whole data is read correctly)

Rerunning the code again, this time decommenting line 19 without touching anything written before, and stepping over the Read function i get in Regs: enter image description here

Again rerunning the code with line 19 decommented and this time stepping in the function Read and running it step by step i get the correct data copied in Regs. So the first question is how is this possible that doing a step by step execution is different from free running the code. The second question is how adding code after function call impacts its outcome. Another thing I noticed is when i try to erase the chip i get this error sometimes, but retrying it gets erased successfully : enter image description here enter image description here enter image description here

Also when I enter in debugging mode on STMide i get this message (it doesnt block me from debugging): enter image description here

Setting breakpoints in different points of the code i also get those before entering in debug mode: enter image description here enter image description here

I have also tried running code without debug mode thinking that the debug instructions could somehow influence the code but the outcome is the same.

1

There are 1 answers

4
gulpr On

You do not show what fram_registers is. If the length of this variable is 4 then everything is fine.

BTW you miss _t in the last parameter so I do not think that it is the actual function you use as it will not compile

  1. You do not need to write your own functions for that (especially invoking undefined behaviour) - you have memcpy.
void Read(uint32_t data_address, uint32_t *data, uint16_t len)
{
    memcpy(data, (void *)data_address, len & (~3);
}
  1. You need to use volatile at both sides: *(volatile uint32_t *)data = *(volatile uint32_t *)data_address;

  2. Delays are not needed as flash can be read as any other memory locations.

  3. The debugger might not read FLASH if you have written something there yourself (it assumes that FLASH is const). I do not use stm32link but J-link requires special option to force FLASH rereads