Skip to main content
January 8, 2024
Solved

Read wrong content of MCU's internal flash

  • January 8, 2024
  • 4 replies
  • 4052 views

Hello

I am working in dual bank mode with STM32G474RET6 MCU. 

I want to store some default values in internal flash beyond last programmed firmware's data address.

For example I have following contents in flash (shown from STM32CubeProgrammer):

AlexHalf_0-1704730435486.png

Data starting at address 0x0804B040 (default values I stored) read as 0xFF. While data before this address as 0x41, 0x53 and etc.. is read correctly.

I tried to store defaults values even at the last blank page starting from address 0x0807F800, but also the same phenomenon - even I verify that it stored correctly - it is read as 0xFF.

Tried to read values with debugger - and in this mode it is working and read correctly.

What could be the problem? Is it some kind of issue with linker and etc??

Please suggest me a solution.

 

My read code for testing:

#define FLASH_DEFAULTS_FLAG_ADD 0x0804B040
#define FLASH1_DEFAULT_VAL_ADD 0x0804B041
#define FLASH2_DEFAULT_VAL_ADD 0x0804B042

uint32_t flash_address ;
__IO uint8_t read_data = 0;

if (HcArg == 0)
flash_address = FLASH_DEFAULTS_FLAG_ADD;
else if (HcArg == 1)
flash_address = FLASH1_DEFAULT_VAL_ADD;
else if (HcArg == 2)
flash_address = FLASH2_DEFAULT_VAL_ADD;
else flash_address = FLASH_DEFAULTS_FLAG_ADD;
read_data = *(__IO uint8_t *)(flash_address);

 

Thank you.

 

Alex

    This topic has been closed for replies.
    Best answer by

    Hello

    I solved this issue. 

    It was flash remapping while working with my STM32G474RET6 in dual bank mode. I discovered that reading values burned to Flash at address 0x807F800 produced different results depending on whether the MCU was running the application image or the boot image.

    When the MCU was running the application image (burned at BANK 2 address starting from 0x8040000), reading from 0x807F800 yielded incorrect results.

    When the MCU was running the boot image (burned at BANK 1 address starting from 0x8000000), reading from 0x807F800 worked as expected.

    Solution: To ensure correct reading of the values from the application image, I adjusted the reading address (in my application image) in my firmware code: I shifted the logical address 0x807F800 to address 0x8037F00.

    While I managed to resolve this challenge, I'd appreciate any further insights or references from the community. Specifically, I'm interested in understanding:

    Are there specific sections or details in the STM32G474 Reference Manual that I may have missed, which explain this remapping behavior in more detail?

    Has anyone else encountered similar situations with dual bank mode and remapping in STM32 devices?

    Thank you.

    4 replies

    Super User
    January 8, 2024

    Flash isn't random access memory. To write to flash, you must unlock the flash, ensure the location you're writing to is erased, and then write the value. Additionally, on the STM32G4 series, you must write 64-bits at a time, aligned.

    See "Flash program and erase operations" in the reference manual.

     

    Graduate II
    January 8, 2024

    Hard to say.

    Perhaps write as words and not as bytes, I don't recall what the flash line widths is with the STM32G4, but let's assume it's not 8-bits, and probably more like 64-bits

    January 8, 2024

    Hello

     

    The problem is not with write (for this I unlock flash, erase, align data for programming to 8 bytes as written in manual, program, verify and lock the flash).

    All data programming (and verification) done by firmware burned at Bank 1. Also, in addition to verification after programming I see that values are written correctly to flash (to correct addresses) by reading these values with STM32CubeProgrammer.

    Next read of these values I want to perform by firmware burned at Bank 2 and here I have a value reading problem.

    So, the problem is only with reading these values (while reading by running debugger of firmware at Bank 2 - is ok).

    Graduate II
    January 8, 2024

    Can you show an equivalent dump from application space?

    Is the application mapping the first or second bank?

    Dump 0x0804B040 and 0x0800B040

    Dump FLASH_OPTR /  32-bit word at 0x1FFF7800

    Can you use a page that's not involved in the end of the firmware image itself?

     

     

     

    January 8, 2024

    Hello

    Tried to use page not adjacent to the firmware like last page address - 0x0807F800.

    The dump of the correct programmed bytes: 

    AlexHalf_0-1704743958041.png

    I burn and verify these bytes (with during burning process from 'boot' image located at Bank 1 (0x8000000 starting address).

    Code from burning process (with uint8_t) - that read correctly burned bytes at 0x0807F800:

      // Verify programmed data
      for (uint32_t i = 0; i < FlashBuffLength; i++)
          {
        flash_data = *(__IO uint8_t *)(FlashProgAddr + i);
     
        if (flash_data != FlashProgramData[i])
        ret_code = 1;
           }

     

    From boot image I 'jump' to application image at Bank 2 (starting address 0x8040000). This image should read the values burned starting from address 0x807F800 (and as you see above - the values are burned).

    Dump of FLASH_OPTR:

    AlexHalf_1-1704744244785.pngAlexHalf_2-1704744339480.pngAlexHalf_3-1704744364147.png

     

    Super User
    January 8, 2024

    from rm:

    AScha3_0-1704735342294.png

    So try read with uint64 or 128, depending on your chip/+bank, maybe working better . :)