Skip to main content
Visitor II
March 6, 2020
Question

Dual Boot on the STM32G4 not quite working (boot from second bank fails)

  • March 6, 2020
  • 6 replies
  • 5121 views

I checked out the example dual boot project from here:

https://github.com/STMicroelectronics/STM32CubeG4/tree/master/Projects/NUCLEO-G474RE/Examples/FLASH/FLASH_DualBoot

I am running this on my G474RE nucleo. What works:

* flashing bank 1 with the bank1 program, I can observe that the BFB2 bit is correctly toggled. But the bank2 program I compiled does not get executed.

* flashing bank 1 with the bank2 program, I can also observe that the BFB2 bit is correctly toggled (as it should), but bank2 is not executed correctly.

* flashing bank 1 with bank1 or bank2 programs and flashing bank 2 with the provided binary: https://github.com/STMicroelectronics/STM32CubeG4/blob/master/Projects/NUCLEO-G474RE/Examples/FLASH/FLASH_DualBoot/Binary/FLASH_DualBoot.bin also works!

So it seems my compilation of flash bank 2 program is somehow incorrect, since the provided binary for flash bank 2 works fine...? Or what is amiss here?

    This topic has been closed for replies.

    6 replies

    Technical Moderator
    June 11, 2020

    Hello @Community member​ ,

    After analysis, this issue is due to bootloader and it has been fixed with bootloader version 13.4.

    So, can you please confirm that you are using a board with bootloader v13.4? or please share the binary of the applications that you load in Bank1 and Bank2 ?

    In fact, the FLASH Dual Boot example is not working as you reported when using bootloader v13.3 and older releases.

    Please follow these steps to ensure that the bootloader version used is v13.4:

    - connect the board to STM32Cubeprogrammer

    - read the address 0x1FFF6FFE

    - the first bytes must have value 0xD4:

    D ==> 13

    4 ==> .4

    Note that the example is working using IAR toolchain and Bootloader v13.4, but we have the same issue as you reported when using Bootloader v13.3 and v13.2 .

    Best Regards,

    Imen

    Visitor II
    June 12, 2020

    Hello Imen,

    Thanks for getting back to me on this issue!

    I had earlier opened an issue with ST Support about the same topic because it was pressing. We troubleshot for a while, noticing that the working binaries that are provided in the cube example have different starting bytes than the ones I was compiling with STM32CubeIDE and which were not working.

    We arrived at the following conclusion: the stm32g474 has 96kb of SRAM at 0x20000000 and 32kb of (CCM-)SRAM at 0x10000000. So 128kb in total. The linker file also configures 128k of SRAM. As the first bytes in the binary point to the first stack frame, when booting an image linked with 128k of SRAM, that address is too high for the boot loader and it (correctly) rejects the image (note that this linker file is autogenerated by cubeMX). Setting the SRAM size to 96k in the linker file fixes the issue: we are happily updating our boards over mqtt and then toggling bfb2 all the time now.

    Here is the case:

    https://community.st.com/s/case/5003W000000V40tQAC/dual-boot-using-bfb2-bit

    Is this just an ugly workaround, now that the bootloader is fixed?

    My bootloader version on the board I have at my desk now is 13.4. However, I have since bricked the other nucleo on which I did discover the issue, so I cannot check the bootloader version there unfortunately :)

    Greetings,

    Rafael

    Technical Moderator
    June 12, 2020

    Thank you @Rafael pour your feedback and status.

    Our development team are working to fix this issue. I will come back to you soon with update.

    Regards,

    Imen

    Technical Moderator
    June 18, 2020

    Hi @MScho.1​ ,

    The Bootloader doesn’t support CCM-SRAM as valid location for stack pointer. So in case of Dual bank boot, if a bank contains stack pointer pointing outside SRAM1 it is considered by the bootloader as non valid, because the CCM-SRAM is not meant for being used as stack location. It could, but that’s not the regular usage it’s meant for. So, Bootloader doesn’t consider it valid for stack pointer.

    In fact, there is no bug in STM32G4 bootloader V13.4, this is how Bootloader works. But our documentation shall be enhanced.

    On newer series however, the CCM-SRAM has been added following received support cases. So your use case would work correctly on that part number.

    Please note that this part is not relative to Bootloader (as dual boot is a function of the system) so this will be raised internally to be documented in the reference manual.

    Note that this recurring problem is raised internally and will be resolved : if SRAM size is 96KB (0x18000). Some Gnu-like compilers/linkers in that case, place the stack pointer at the address 0x200180000. And that will fail with Bootloader because the last physical address in SRAM is 0x20017FFFF not 0x200180000. So linker will be fixed to take into account the right address.

    Hope my answer helps you.

    Best Regards,

    Imen

    Graduate II
    May 14, 2021

    Hello Imen,

    Thank you for looking into this issue, but I would like some clarification please: My STM32G474 has bootloader version 13.0. If I keep the stack pointer below 0x20018000 (less than 96K) can I dual boot, even though I have such an early bootloader?

    I appreciate any insight you can offer - thank you!

    Regards,

    Dave

    Graduate II
    May 18, 2021

    Hello,

    CORRECTION: Turns out I have bootloader 13.4 (I mistakenly thought the second byte was significant and mine is 0x00). The first byte is 0xD4, so I appear to have 13.4.

    Dave

    Technical Moderator
    July 2, 2020

    Please refer to the latest STM32CubeG4 firwmare package version 1.3.0 with fix on the DUAL BOOT example and the linker file.

    Visitor II
    November 18, 2020

    Hi

    I am kind of stuck with using BFB2 bit for switching banks in G474 MCU for OTA support.

    I could see that the BFB2 bit option byte was switched successfully using my program, but the device still did not boot from the Bank 2.

    I have verified that the current system bootloader version is 13.4.

    BOOT0 pin was set to 0 in the hardware. 

    For a hardware-specific reason, I had to disable the system bootloader configuring the option bytes to nSWBOOT0=0 and nBOOT0=1 using ST Link utility.

    Later I realized that for BFB2 to work, I may have to enable the system BL. 

    In order to check this manually, I flashed two binaries in Bank 1 and Bank 2.

    Also configured nSWBOOT0=0 and nBOOT0=0 to enable the system BL and then BFB2=1 was set.

    From now on, the device keeps giving me programming errors, for example,

    "Programming error @ 0x08000BA4!"

    Even reverting to the older option bytes configuration also gives the same error. This is the second device that is giving me the same issue.

    Is there anything that I have to do to make the MCU programmable again? I do not know what is wrong with my configurations.

    Visitor II
    November 18, 2020

    I'm not sure if this is related to your problem, but AFAIK the ST Link Utility does not fully support the option bytes of STM32G4 controllers, you should use CubeProgrammer instead. I think some of the bits are not accessible on ST-Link Utility and some have weird naming/polarity mismatches with the datasheet.

    Maybe that messed something up in your option bytes configuration?

    Visitor II
    November 18, 2020

    Thanks for the reply. You may be right.

    Is there any way to reset the option bytes to factory, say using the STM32CubeProgrammer or any other means?

    Visitor II
    May 6, 2021

    Dear.

    I have this same problem, but with stm32l073RZ.

    More explicitly, my code with a flashing led works on bank1, but it does not work on bank2. The strangest thing is that I also used the sample code for an intermittent led from stmcubel0 and it works, but with mine it only turns on the led but in low light.

    I'm using stmcubeide, could this be the problem?

    I used the stmcubeprogramer to change the banks.