Showing results for 
Search instead for 
Did you mean: 

What am i not setting up right with dualbooting an STM32G474VET?

Associate II


I am trying to implement dual bank booting on a stm32G474VET6 and im am doing the flashing of the other bank via Intel HEX decoding from an SD card.

In order to test if I am successful, i have flashed my software via cubeprogrammer from the same hex file that i then store on the SD card. Cubeprogrammer is used to flash to the normal 0x08000000 address but my Intel HEX decoder knows that it shall always offset the address and thus it starts to write to 0x08400000.

I have also used a small loop to compare the entire flash area byte by byte and they do match.

But now the programs in my two banks are identical. It would be impossible to tell which bank is executing. For that reason I have added printouts like this:

printf("Executing Bank %u\r\n", (((SYSCFG->MEMRMP & SYSCFG_MEMRMP_FB_MODE) != 0u) ? 2u : 1u));
printf("Requested Bank %u\r\n", ((FLASH->OPTR & (1u << 20u)) != 0u) ? 2u : 1u);
// Are we on a chip with a working bootloader?
uint32_t* pSystem_bootloder_version = (uint32_t*)(0x1FFF6FFEu);
uint8_t bootloader_major = (*pSystem_bootloder_version & 0xF0u) >> 4u;
uint8_t bootloader_minor = (*pSystem_bootloder_version & 0x0Fu);
printf("System bootloader %u.%u\r\n",  bootloader_major, bootloader_minor);  // prints 13.4

When I set DBANK and unset BFB2 (via cubeprogrammer) it prints executing bank1 and requested bank1. When I change to BFB2 it says executing bank1 and requested bank2.

My ld file is changed to:

/* Highest address of the user mode stack */
/* Normal variant*/
/* _estack = ORIGIN(RAM) + LENGTH(RAM); */	/* end of "RAM" Ram type memory */
/* Variant that works with the internal bootloader */
_estack = ORIGIN(RAM) + 0x18000;    /* end of "SRAM" type memory */
_Min_Heap_Size = 0x200;	/* required amount of heap  */
_Min_Stack_Size = 0x400;	/* required amount of stack */
/* Memories definition */
  RAM   	(xrw)   : ORIGIN = 0x20000000,   LENGTH = 128K
  FLASH		(rx)    : ORIGIN = 0x8000000,    LENGTH = 256K
  FLASH_O	(rx)    : ORIGIN = 0x8040000,    LENGTH = 256K

The introduction of FLASH_O is to ensure that my program does not grow out of control and overwrites into the other bank.

The value at 0x08000000 and 0x08040000is 0x20018000 according to cubeprogramer.

What am i doing wrong? Why wont the system boot from BANK2?

Best regards


Associate III

Hello Martin,

Are you unlocking and writing the option bytes somewhere? After that, they take effect at the next reset or immediately if you "launch" them.



> they take effect at the next reset

Just a simple (system) reset is not enough. RM0440 Rev7 section 3.4.2 "Option bytes programming":

Option bytes loading (OBL) is performed in two cases:

– when OBL_LAUNCH bit is set in the Flash control register (FLASH_CR).

– after a power reset (BOR reset or exit from Standby/Shutdown modes).

Associate II

Just to follow up for anyone finding this post.

The problem seemd to be in the option bytes. I am not sure how it had happened, but the board i was testing had alot of weird optionbyte settings. After I switched to a new board everything worked as expected.