Skip to main content
Associate III
June 24, 2025
Solved

Error jumping to application from default bootloader

  • June 24, 2025
  • 1 reply
  • 466 views

Hello,

I have 2 STM32 Nucleo F746ZG boards, and I am trying to use one board (MCU 1) to program the second board (MCU 2) through its default bootloader through code. To do so, I used the following command in the MCU2 to start its default bootloader:

#define DEFAULT_BOOTLOADER_ADDRESS 0x1FF00000
BOOT_JumpToAddress(DEFAULT_BOOTLOADER_ADDRESS);

void BOOT_JumpToAddress(uint32_t address)
{
 printf("Jumping to 0x%08X\r\n", address);

 // Function pointer to reset handler
 void (*app_reset_handler)(void) = (void *)(*((volatile uint32_t *)(address + 4U)));

 // Disable RCC, HAL, reset SYSTICK, and remap vector table offset
 HAL_RCC_DeInit();
 HAL_DeInit();
 SysTick->CTRL = 0;
 SysTick->LOAD = 0;
 SysTick->VAL = 0;
 SCB->VTOR = address;
 uint32_t msp_value = *((volatile uint32_t *)address);
 __set_MSP(msp_value);
 // Jump into application
 app_reset_handler();
}

 Then, on the programmer, I send the start byte 0x7F. When I receive ACK, I send the bytes for the "Go to application" command, which are 0x21 and 0xDE. After receiving ACK, I send the bytes for the address and the checksum using the command below:

uint32_t applicationAddress = 0x08040000;
addrBuf[0] = (applicationAddress >> 24) & 0xFF;
addrBuf[1] = (applicationAddress >> 16) & 0xFF;
addrBuf[2] = (applicationAddress >> 8) & 0xFF;
addrBuf[3] = (applicationAddress >> 0) & 0xFF;
addrBuf[4] = addrBuf[0] ^ addrBuf[1] ^ addrBuf[2] ^ addrBuf[3];

 

I send that buffer, and I get back ACK. When I monitor the PuTTY output on my MCU2, I can see that "Starting appl" has been printed out, which indicates that the bootloader jumped to the application slot, as that printf statement is printed after all the configurations is done. However, the entire string is not printed, and instead after that printf statement, the MCU 2 starts running the custom bootloader, another project that I am trying to do.

So, why does that happen? I think that something causes the MCU2 to reset while it is running the application code, causing it to default to running the custom bootloader (this behaviour is expected: I have set it such that whenever the MCU 2 resets, it runs my custom bootloader first). Does the BOOT0 pin need to be held high while I am running the default bootloader code? Right now, I have not been messing with it. Or do I need to set SCB->VTOR = 0x08040000 somewhere?

The problem is not with the application code, because it runs fine if I run it on its own.

I would greatly appreciate any help. Thank you! 

Best answer by Saket_Om

Hello @is45 

The relocation of VTOR is done in the SystemInit function. It is called immediately after the microcontroller is reset and before the main() function is called.

See the example bellow: 

void SystemInit(void)
{
 /* FPU settings ------------------------------------------------------------*/
 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
 #endif
 /* Reset the RCC clock configuration to the default reset state ------------*/
 /* Set HSION bit */
 RCC->CR |= (uint32_t)0x00000001;

 /* Reset CFGR register */
 RCC->CFGR = 0x00000000;

 /* Reset HSEON, CSSON and PLLON bits */
 RCC->CR &= (uint32_t)0xFEF6FFFF;

 /* Reset PLLCFGR register */
 RCC->PLLCFGR = 0x24003010;

 /* Reset HSEBYP bit */
 RCC->CR &= (uint32_t)0xFFFBFFFF;

 /* Disable all interrupts */
 RCC->CIR = 0x00000000;

 /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

 

1 reply

Technical Moderator
June 24, 2025

Hello @is45 

Before jumping to the application, ensure that SCB->VTOR is set to the application's base address (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"
is45Author
Associate III
June 24, 2025

Hello, as I am sending commands to the default bootloader on MCU 2, shouldn't default bootloader set the SCB->VTOR in its internal functions?

Saket_OmBest answer
Technical Moderator
June 24, 2025

Hello @is45 

The relocation of VTOR is done in the SystemInit function. It is called immediately after the microcontroller is reset and before the main() function is called.

See the example bellow: 

void SystemInit(void)
{
 /* FPU settings ------------------------------------------------------------*/
 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
 #endif
 /* Reset the RCC clock configuration to the default reset state ------------*/
 /* Set HSION bit */
 RCC->CR |= (uint32_t)0x00000001;

 /* Reset CFGR register */
 RCC->CFGR = 0x00000000;

 /* Reset HSEON, CSSON and PLLON bits */
 RCC->CR &= (uint32_t)0xFEF6FFFF;

 /* Reset PLLCFGR register */
 RCC->PLLCFGR = 0x24003010;

 /* Reset HSEBYP bit */
 RCC->CR &= (uint32_t)0xFFFBFFFF;

 /* Disable all interrupts */
 RCC->CIR = 0x00000000;

 /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

 

"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"