Skip to main content
Associate II
April 8, 2025
Solved

Writing to Bank1 while running from Bank2 → Flash write fails

  • April 8, 2025
  • 6 replies
  • 2123 views

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!

Best answer by Saket_Om

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;

 

6 replies

Technical Moderator
April 8, 2025

Hello @cuong 

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

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question.Saket_Om"
pikachu
Associate
April 8, 2025

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_OmBest answer
Technical Moderator
April 8, 2025

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;

 

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question.Saket_Om"
pikachu
Associate
April 9, 2025

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.

cuongAuthor
Associate II
April 9, 2025

Hello @omar_12129,

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

 

cuongAuthor
Associate II
April 10, 2025

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!

Explorer II
May 22, 2025

Hi @cuong 
I have the same problem on STM32L4A6. The entire OTA is prepared for DualBoot. The update from BANK1 to BANK2 works correctly.
And suddenly, in the next iteration, the application from BANK2 cannot write to BANK1. Erasing works without any issues.
Were you able to find a solution?

cuongAuthor
Associate II
May 23, 2025

Hi ufolek

Yes, I’ve encountered a very similar issue and managed to solve it.

In my case, the MCU is not an STM32L4A6, but an STM32G474.
The root cause turned out to be related to the remapped memory layout when booting from Bank2 with BFB2 = 1.

When the device starts from Bank2 (with BFB2 = 1 set), the memory map is remapped as follows on STM32G4 series:

  • Bank2 is remapped to 0x08000000 (the usual start address),

  • Bank1 is remapped to 0x08040000 (instead of its usual 0x08000000).

So if you try to write to 0x08000000 from an application running in Bank2, you're actually attempting to write to Bank2 (which is currently executing), not Bank1 — and that causes the write to fail.

Solution:

To write to Bank1 while executing from Bank2, use the remapped address 0x08040000 instead of 0x08000000.

Hope this helps!

cuongAuthor
Associate II
August 18, 2025

Thank you@PCu1 

I’ve already managed to solve it.
Thank you for reaching out!