cancel
Showing results for 
Search instead for 
Did you mean: 

Writing to Bank1 while running from Bank2 → Flash write fails

cuong
Associate

Hi everyone,

I'm using STM32G474 with dual-bank Flash enabled (nDBANK = 0) and booting from Bank2 (BFB2 = 1). I'm implementing OTA firmware update by writing to the inactive bank while executing from the active one.

The update from Bank1 → Bank2 works fine.

But in the second update cycle, when running from Bank2 and trying to write to Bank1 (starting at address 0x08000000), HAL_FLASH_Program() always fails on the first double-word.

I have:

  • Verified that Write Protection is disabled (checked in STM32CubeProgrammer)

  • Unlocked Flash properly

  • Erased the target pages beforehand

  • No PCROP or secure area configured on Bank1

  • Flash error flag is HAL_FLASH_ERROR_WRITE_PROTECTION sometimes (even though WRP is not set)

I found some similar cases reported online (e.g. this one) where users mentioned that writing to Bank1 from Bank2 fails silently.

Is there an undocumented silicon limitation on STM32G4 when programming Bank1 from Bank2?

I would appreciate any official clarification or workaround from ST or others who solved this.

Thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
Saket_Om
ST Employee

Hello @cuong and @pikachu 

I updated the example Projects/STM32G474E-EVAL1/Examples/FLASH/FLASH_DualBoot to boot on flash BANK2 and write on flash BANK1. It works fine without errors. 

Please find attached the updated main.c and main.h. 

Also, the linker file shall be updated with the below line to be able to upload directly from IAR the binary data to flash BANK2:

define symbol __ICFEDIT_intvec_start__ = 0x08040000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__     = 0x08040000;

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

View solution in original post

6 REPLIES 6
Saket_Om
ST Employee

Hello @cuong 

Your issue has been reported internally and will get back to you as soon as possible. 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar
pikachu
Associate

I'm not having exactly the same problem, but it feels very similar, I just opened another post today.

https://community.st.com/t5/stm32-mcus-products/stm32g4-dual-bank-page-erase-blocking-interrupts-from-bank-2-to/td-p/791211

In my case the problem is when I erase Bank 1 from Bank 2 (the IRQ stops for too long and this generates a lot of other problems) but the weird thing is that this is also not happening when doing the same actions from Bank 1 to Bank 2. 

Everything works perfectly in Bank 1, but when I'm in Bank 2 doing the same, I have a lot of problems. In my case I'm able to write, but erases are a mess. 

I don't know...

Saket_Om
ST Employee

Hello @cuong and @pikachu 

I updated the example Projects/STM32G474E-EVAL1/Examples/FLASH/FLASH_DualBoot to boot on flash BANK2 and write on flash BANK1. It works fine without errors. 

Please find attached the updated main.c and main.h. 

Also, the linker file shall be updated with the below line to be able to upload directly from IAR the binary data to flash BANK2:

define symbol __ICFEDIT_intvec_start__ = 0x08040000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__     = 0x08040000;

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar
cuong
Associate

Hello @omar,

Thank you very much for sharing the updated example and linker settings.

I have one follow-up question:
In my project, I am using a dual-bank firmware update mechanism, where:

- If the MCU is running from Bank1, it writes firmware to Bank2
- If it's running from Bank2, it writes firmware to Bank1

To simplify the workflow, I am trying to **use the same `.bin` file** (built with vector table at 0x08000000) for both cases — writing it to either Bank1 or Bank2 depending on the current boot bank.

So my question is:
**Is it strictly necessary to change the linker symbols (`__ICFEDIT_intvec_start__ = 0x08040000`) when writing to Bank2,** if I handle the vector table relocation manually in code by setting `SCB->VTOR` accordingly at runtime?

Also, I have checked the `main.c` and `main.h` files that you kindly shared, and I confirmed that they are essentially the same as my current implementation. However, I still cannot write to Bank1 when the MCU is running from Bank2 (even though the reverse direction works fine). So I'm wondering if there might be any subtle configuration differences or flash-related constraints that I'm missing?

Would greatly appreciate your advice or any insights for this scenario — especially for IAR-based projects.

Thanks again!

cuong_0-1744167302499.pngcuong_1-1744167413908.pngcuong_2-1744167439383.png

cuong_3-1744167477651.png

 

Thank you @Saket_Om, but my problem is not exactly the same, so this doesn't fix it. Refer to my post for more info, but the problem in my case is only when erasing a page in Bank 1 when Bank 2 is active (the other way around works perfectly).

There's probably some limitation that I'm not seeing in how dual boot works.

cuong
Associate

Hello @Saket_Om,

Thank you very much for sharing the updated example and linker settings.

I have one follow-up question:
In my project, I am using a dual-bank firmware update mechanism, where:

- If the MCU is running from Bank1, it writes firmware to Bank2
- If it's running from Bank2, it writes firmware to Bank1

To simplify the workflow, I am trying to **use the same `.bin` file** (built with vector table at 0x08000000) for both cases — writing it to either Bank1 or Bank2 depending on the current boot bank.

So my question is:
**Is it strictly necessary to change the linker symbols (`__ICFEDIT_intvec_start__ = 0x08040000`) when writing to Bank2,** if I handle the vector table relocation manually in code by setting `SCB->VTOR` accordingly at runtime?

Also, I have checked the `main.c` and `main.h` files that you kindly shared, and I confirmed that they are essentially the same as my current implementation. However, I still cannot write to Bank1 when the MCU is running from Bank2 (even though the reverse direction works fine). So I'm wondering if there might be any subtle configuration differences or flash-related constraints that I'm missing?

Would greatly appreciate your advice or any insights for this scenario — especially for IAR-based projects.

Thanks again!