cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743xG - How to handle the gap between the two flash banks for bootloading ?

SMarie
Associate III

Hello everyone.

 

I am currently working on a bootloader with a STM32H743VGT6.

I need to write data on both banks which aren't continuous as you can see below:

 

SMarie_2-1719928497471.png

 

It was recommended in this topic to use HEX format, but I need to stick to bin files.

 

So my question is:

Can I set all the data in the bin file from 0x0808 0000 to 0x080F FFFF to the value 0xFF?

Or do I need to find an other solution? Like using two bin files (which I'd like to avoid).

 

Thank you in advance for your help.

Best regards,
Sulian

1 ACCEPTED SOLUTION

Accepted Solutions
SMarie
Associate III

Hi everyone,
Thank you very much to you all for your help!

To recap, my MCU does indeed have a 2 MB flash die. But only the first four sectors of each bank are tested and recommended to work with.


When the bin file is generated, the gap between the two banks is filed with 0x00.
The solution we have used is:
The bootloader reads the bin file piece by piece and write it to the flash, then increment it. When it starts reading the part corresponding to the gap, it stops writing until it reaches the second bank start address.

 

 

  uint32_t ram_address = 0, last_pga_address = 0, read_size = 0;
  bool read_flag = true;

  /** RAM Address initialization */
  ram_address = (uint32_t)(&RamBuffer);

  /** Programm address init */
  last_pga_address = APPLICATION_STARTADDRESS;

  while(read_flag == true)
  {
    if(iap_read_file(RamBuffer, IAP_BUFFER_SIZE, &read_size) != RET_OK)
    {
      return RET_ERROR;
    }

    /* The read data < "BUFFER_SIZE" Kbyte */
    if(read_size < IAP_BUFFER_SIZE)
    {
      read_flag = false;
    }

    /* Ignore addresses between 0x08080000 and 0x08100000 */
    if((last_pga_address < FLASH1_M_ENDADDRESS) || (last_pga_address >= FLASH2_M_STARTADDRESS))
    {
      if(Flash_Write(last_pga_address, read_size, ram_address) != RET_OK)
      {
        return RET_ERROR;
      }
    }
    /* Update last programmed address value */
    last_pga_address += read_size;
  }

 

 

That wasn't a big deal, but I really wanted to understand why/how it worked when it wasn't supposed to.

Thank you all again.

View solution in original post

7 REPLIES 7

You could use a single linear binary, where you *know* when writing it to memory that you need to skip forward 512KB after writing the first 512KB

addr += 128; // example when writing 128-byte blocks
if (addr == 0x08080000) addr += 0x800000; // skip count from 0x0807FFFF to 0x08100000 when writing

Are we sure there's not 2MB on die?

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

@SMarie This picture is for STM32H742 or other models with a hole between banks. Your STM32H743 does not have a hole. Bank 2 begins immediately after bank1, so no problem.


@Tesla DeLorean wrote:

You could use a single linear binary, where you *know* when writing it to memory that you need to skip forward 512KB after writing the first 512KB


Yes that might be a good alternative. I'll try this way.


@Tesla DeLorean wrote:

Are we sure there's not 2MB on die?


Well that's the tricky part that I don't understand. The documentation does specify that it is a 1MB of two 512KB bank with a 512KB gap between them.

Which is also what I get in my STM32H743ZGTX_FLASH.ld file:

MEMORY
{
  FLASH (rx)     : ORIGIN = 0x08000000, LENGTH = 512K
  FLASH2 (rx)    : ORIGIN = 0x08100000, LENGTH = 512K
  DTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K
  RAM_D1 (xrw)   : ORIGIN = 0x24000000, LENGTH = 512K
  RAM_D2 (xrw)   : ORIGIN = 0x30000000, LENGTH = 288K
  RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K
  ITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K
}

 

But until recently, we didn't really needed the FLASH2, and we only used it to put our CRC value at the end.

But we didn't noticed this gap and so the value instead of being at the address 0x0817 FFFC (the end of bank 2), was at the address 0x080F FFFC (at the end of the gap just before the bank 2).

Yet we didn't observe any bug and the code was working fine...

I am not sure we can keep putting data there.


@Pavel A. wrote:

@SMarie This picture is for STM32H742 or other models with a hole between banks. Your STM32H743 does not have a hole. Bank 2 begins immediately after bank1, so no problem.


It does look like it because we where putting data in this gap and it didn't get loose.

Nevertheless, the picture does include STM32H743xG models which I am using and it corresponds with the STM32H743ZGTX_FLASH.ld file:

MEMORY
{
  FLASH (rx)     : ORIGIN = 0x08000000, LENGTH = 512K
  FLASH2 (rx)    : ORIGIN = 0x08100000, LENGTH = 512K
  DTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K
  RAM_D1 (xrw)   : ORIGIN = 0x24000000, LENGTH = 512K
  RAM_D2 (xrw)   : ORIGIN = 0x30000000, LENGTH = 288K
  RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K
  ITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K
}

 

Are you sure this gap can be use as a regular flash ?

Pavel A.
Evangelist III

Hmm, your STM32H743 belongs to the "xG" type. It still can have 8 sectors per bank instead of 4. But sectors 4-7 are not factory-tested and may be defective (excluded from warranty). You can test these sectors by yourself. If they appear good...  use them on your own risk.

As for how to deal with the hole - it is quite large, so either make two binaries or use .hex or other format that contains the addresses.

Hi,

to explain it : the die is (until now) the same, with 2 MB flash.

BUT what you buy with STM32H743xG is : 1MB (in 2 x  512K banks) is tested and guaranteed to work.

With STM32H743xI you pay more for tested 2MB (in 2 x 1MB banks). Thats it.

So the full 2MB is there and you can use it, maybe just set the (new) project to STM32H743xI , then linker knows.

But : you have no safety, if a part of the "not payed" area not working - bad luck.

Or if STM decides, to block the access to "wrong" flash addresses, then get hard error.

(I dont know, whether they can or will do this , but its possible and you have no "right" to  complain then.)

If you feel a post has answered your question, please click "Accept as Solution".
SMarie
Associate III

Hi everyone,
Thank you very much to you all for your help!

To recap, my MCU does indeed have a 2 MB flash die. But only the first four sectors of each bank are tested and recommended to work with.


When the bin file is generated, the gap between the two banks is filed with 0x00.
The solution we have used is:
The bootloader reads the bin file piece by piece and write it to the flash, then increment it. When it starts reading the part corresponding to the gap, it stops writing until it reaches the second bank start address.

 

 

  uint32_t ram_address = 0, last_pga_address = 0, read_size = 0;
  bool read_flag = true;

  /** RAM Address initialization */
  ram_address = (uint32_t)(&RamBuffer);

  /** Programm address init */
  last_pga_address = APPLICATION_STARTADDRESS;

  while(read_flag == true)
  {
    if(iap_read_file(RamBuffer, IAP_BUFFER_SIZE, &read_size) != RET_OK)
    {
      return RET_ERROR;
    }

    /* The read data < "BUFFER_SIZE" Kbyte */
    if(read_size < IAP_BUFFER_SIZE)
    {
      read_flag = false;
    }

    /* Ignore addresses between 0x08080000 and 0x08100000 */
    if((last_pga_address < FLASH1_M_ENDADDRESS) || (last_pga_address >= FLASH2_M_STARTADDRESS))
    {
      if(Flash_Write(last_pga_address, read_size, ram_address) != RET_OK)
      {
        return RET_ERROR;
      }
    }
    /* Update last programmed address value */
    last_pga_address += read_size;
  }

 

 

That wasn't a big deal, but I really wanted to understand why/how it worked when it wasn't supposed to.

Thank you all again.