cancel
Showing results for 
Search instead for 
Did you mean: 

Jump to bootloader from application on STM32H7 devices

Khouloud GARSI
Lead II

Using STM32H7 MCUs, how to jump into system bootloader from application code?

In STM32H7, the base address of system memory is different from the entry point of the bootloader.  Thus, in order to jump to the bootloader, address "0x1FF09800" should be used instead of "0x1FFF0000".  Below, you find a sample code permitting the jump to the bootloader in STM32H7 devices:

void JumpToBootloader(void)
{
  uint32_t i=0;
  void (*SysMemBootJump)(void);
 
  /* Set the address of the entry point to bootloader */
     volatile uint32_t BootAddr = 0x1FF09800;
 
  /* Disable all interrupts */
     __disable_irq();

  /* Disable Systick timer */
     SysTick->CTRL = 0;
	 
  /* Set the clock to the default state */
     HAL_RCC_DeInit();

  /* Clear Interrupt Enable Register & Interrupt Pending Register */
     for (i=0;i<5;i++)
     {
	  NVIC->ICER[i]=0xFFFFFFFF;
	  NVIC->ICPR[i]=0xFFFFFFFF;
     }	
	 
  /* Re-enable all interrupts */
     __enable_irq();
	
  /* Set up the jump to booloader address + 4 */
     SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr + 4))));
 
  /* Set the main stack pointer to the bootloader stack */
     __set_MSP(*(uint32_t *)BootAddr);
 
  /* Call the function to jump to bootloader location */
     SysMemBootJump(); 
  
  /* Jump is done successfully */
     while (1)
     {
      /* Code should never reach this loop */
     }
}

   

Comments
Mmadh
Associate II

I want learn led lighting program stvp and STVD plz help it's my mail suryamadhu58@outlook.com​

Mmadh
Associate II

I full confused ​

Brian Kling
Senior III

@Mmadh​  if you have a question please post it using the Q&A section in the global navigation bar.

Kirill Makukhin
Associate

I'm trying to implement this on stm32h743zit6, but no luck. The MCU just reboots instead of switching to a bootloader (as it does with the BOOT pin). What do I miss? Any specific option bytes or control registers perhaps?

Camilo LEMOS
Senior II

Hello @Kirill Makukhin​ !

If you have a question please post it using the Q&A section in the global navigation bar at the top of this page.

Thank you!

haleecaero.1
Associate II

This is useful, however I'd like to point out that if you are not jumping to the system bootloader, but e.g.: between a user bootloader and a user application that is located somewhere else than at 0x08000000, you will most likely need to update the interrupt vector with

```

SCB->VTOR = addr;

```

This is initialised to the default value of 0x08000000 by `SystemInit()` and so you have to make this change _after_ the jump (in case you are jumping to a place that calls `SystemInit()`, as it's likely the case). AFAICT, this cannot be done via the H7 HAL. There are a handful of places where this has been raised for other versions of the HAL (e.g.: https://github.com/STMicroelectronics/STM32CubeL0/pull/10, https://github.com/STMicroelectronics/STM32CubeF4/pull/64 ).

Ahmet Yasin CİVAN
Associate III

I want to draw attention to the versions. I couldn't get the system bootloader to work with UART2 as my PB15 is not connected to GND. If the STM32H747 system bootloader version is V9.0, the PB15 must be connected to GND.


_legacyfs_online_stmicro_images_0693W00000KaxGKQAZ.png

MMARC.1
Associate II

Just to add a clarification, system memory bootloader address is mentioned on AN2606 and for STM32H7 it always differs from system memory base address. On STM32H72/3/4/5 bootloader address is  0x1FF09800 while for STM32H7A/B it is 0x1FF0A000.

heveskar
Senior

Hi,

In the ICER and ICPR register reset loop, why are you resetting only 5 registers when sometimes there are used more? On STM32H723 we are using, there are used NVIC positions up to 162:


_legacyfs_online_stmicro_images_0693W00000biILhQAM.png(source: RM), which means that those three interrupts are not disabled and it may cause issues (I just encountered those, that's how I know).

Wouldn't it be better to use something like

uint8_t cnt = (sizeof(NVIC->ICER) / sizeof(*NVIC->ICER));
  for (i = 0; i < cnt; i++)
  {
    NVIC->ICER[i] = 0xFFFFFFFF;
    NVIC->ICPR[i] = 0xFFFFFFFF;
  }

just to be sure? This writes to all the registeres that are defined in the structure, I know that it is more than needed but it seems to be the better approach than use magic number "5".

Karel

heveskar
Senior

Another thing, I may be mistaken, but in the first paragraph, it seems that System Memory base address is 0x1FFF0000, shouldn't it be 0x1FF00000? I think the same problem is in the application note AN2606, where there is mentioned that (for STM32H72xxx/73xxx): "128 Kbytes starting from address 0x1FFF0000, contain the bootloader firmware." I think that there, too, should be 0x1FF0 0000.

Furthermore, this might not be the right place to mention this, but in the reference manual:


_legacyfs_online_stmicro_images_0693W00000biNg1QAE.pngthe range given for System Memory seems very strange to me, as the supposed ending address is 1 byte lower than the beginning one...

Mohan30
Associate

Hi, I tried to work in the custom bootloader, so I created three application part, one managing the Bootloader and the application, 2nd one is the bootloader, 3rd one is the application, They are individually working perfect, but I tried to jump concept these are not working well, I gave the different memory location and also change the vector address, but is not working well, still I confused, what to do before jumping the application? 
I used the stm32f103c8 controller, I developed the bare metal code using Keil software, can you explain before jumping the application Reset the peripherals concept please give the code format.
Thanks.
@heveskar , @MMARC.1 , @Ahmet Yasin CİVAN , @Khouloud GARSI@haleecaero.1 

Version history
Last update:
‎2023-12-07 05:48 AM
Updated by: