ExplicitBootloaderJump
Jump to navigation
Jump to search
Work in progress, STM32H562 being tested on.
#include "stm32h5xx_hal.h"
#include "jump-bootloader.h"
#define SYSMEM_BOOT_ADDRESS ((uint32_t)0x0BF97000) // Not certain, but
/**
* @brief Jumps to the system memory bootloader.
*/
void JumpToBootloader(void) {
// --- Step 1: De-initialize the system ---
// Disable all interrupts
__disable_irq();
// De-initialize all HAL-configured peripherals
HAL_DeInit();
// De-initialize the RCC (clock system) to its reset state
// This is important for the bootloader to configure the clocks correctly.
HAL_RCC_DeInit();
// Clear any pending interrupts from the NVIC
for (IRQn_Type i = 0; i < 240; i++) { // STM32H5 has up to 240 interrupts
NVIC_DisableIRQ(i);
NVIC_ClearPendingIRQ(i);
}
// Disable SysTick timer and clear its exception pending bit
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
// --- Step 2: Prepare for the jump ---
// Get the bootloader's entry address (Reset_Handler)
// The second word (at address + 4) of the bootloader's vector table
// contains the entry point.
uint32_t bootloader_entry = *(volatile uint32_t*) (SYSMEM_BOOT_ADDRESS + 4);
// Function pointer for the bootloader entry
void (*SysMemBootJump)(void);
// Create a function pointer to the bootloader's entry address
SysMemBootJump = (void (*)(void)) bootloader_entry;
// --- Step 3: Set the stack pointer and jump ---
// Set the main stack pointer (MSP) to the bootloader's initial stack value.
// The first word (at the base address) of the bootloader's vector table
// contains the initial MSP value.
__set_MSP(*(volatile uint32_t*) SYSMEM_BOOT_ADDRESS);
// Execute the jump to the bootloader
SysMemBootJump();
// The program should never reach this point
while (1)
;
}