cancel
Showing results for 
Search instead for 
Did you mean: 

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

Rafael Bachmann
Associate II

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?

16 REPLIES 16
Imen.D
ST Employee

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

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

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

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

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

@Imen DAHMEN​ I do see the same problem with my Nucleo-G474RE board and it has bootloader revision 13.4 (see screenshot attached)

Dual boot only works when the stack pointer in the linker script is set to 0x20018000 (96K) or below (the RAM length can be set to 128K, only the stack pointer address is important). As soon as the initial stack pointer address goes into CCM-SRAM alias beyond 0x20018000 the dual boot is no longer working.

However, I consider placing the stack in CCM-SRAM section as valid practice, so I think this a bug.

I attached the binary files for reference, compiled from the official example code with STM32CubeIDE V1.3.0

Edit:

I noticed also that the fallback mechanism to bank1 is not working when the stack pointer is within the CCMSRAM region. However, when setting the first address manually to some obviously invalid address, the bootloader detects that and correctly falls back to boot from bank1.

To me this sounds like a bug in the bootloader?

Regards

You are right @MScho.1​ , this is the full analysis and the fix

of CubeIDE dual boot example will be implemented in the next release plan (will be available in few weeks) by omitting the CCM SRAM from the user stack space.

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

I assume by release you mean a new bootloader revision. Is there a way I can update the bootloader of my STM32G4 MCUs?

Hi @MScho.1​ ,

Unfortunately, that's not possible to update the bootloader in your side.

Besides, there is no problem with Bootloader in your case as you are using Bootloader revision 13.4 (issue faced with bootloader v13.3 and older releases), but the issue now is with the CubeIDE linker file.

The fix will be available next week in the new release of STM32CubeG4, in this meantime you can update linker CubeIDE (STM32G474RETX_FLASH.ld file) in line 57:

/* Highest address of the user mode stack */

_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

should be :

_estack = ORIGIN(RAM) + 0x18000 ;   /* end of "SRAM" type memory */

Hope this helps you.

Best Regards,

Imen

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

Well, the default stack address in the Cube-generated linker file is only part of the problem I think.

I actually want to place my stackpointer in CCM-SRAM at 0x20020000 (aliased address space) or 0x10008000 (native address space). The problem is that the bootloader Rev 13.4 obviously doesn't support booting from bank 2 in this case. (The main reason I want to place stack in CCM-SRAM is that I can use the write protection feature of CCM-SRAM to place guard pages next to stack to provide handling/detection of stackoverflow)

I'm quite sure that there is a bug in the bootloader with Rev13.4:

  1. The bootloader should support placing the stackpointer in CCM-SRAM
  2. If there is a valid reason not to support this, then the fall-back mechanism to bank1 is broken in this case.

In any case these issues are worth a note in the errata IMHO.

Regards,

Matthias

Imen.D
ST Employee

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

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