2023-06-28 07:57 AM
Hello,
when trying to jump from my application to system bootloader, I get an HardFault exception.
This is the jumping routine that I am using, based on the following ST tutorial:
https://community.st.com/t5/stm32-mcus/how-to-jump-to-system-bootloader-from-application-code-on-stm32/ta-p/49424
#define SYSTEM_MEMORY_ADDR 0x1FFF0000
#define BOOTLOADER_ENTRY_ADDR (SYSTEM_MEMORY_ADDR + 4)
void JumpToBootloader(void)
{
ADC_HandleTypeDef hadc;
UART_HandleTypeDef huart;
SPI_HandleTypeDef hspi;
TIM_HandleTypeDef htim;
void (*f)(void);
uint8_t i;
/* Disable all interrupts */
__disable_irq();
/* Disable Systick timer */
SysTick->CTRL = 0;
/* Set the clock to the default state */
HAL_RCC_DeInit();
/* Disable all other peripherls */
hadc.Instance = ADC1;
HAL_ADC_DeInit(&hadc);
huart.Instance = USART2;
HAL_UART_DeInit(&huart);
hspi.Instance = SPI1;
HAL_SPI_DeInit(&hspi);
htim.Instance = TIM2;
HAL_TIM_Base_DeInit(&htim);
/* 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 the main stack pointer to the boot loader stack */
__set_MSP(*(uint32_t *) SYSTEM_MEMORY_ADDR);
/* jump to bootloader */
f = (void (*)(void)) BOOTLOADER_ENTRY_ADDR;
f();
}
Thank you,
Daniele
2023-06-28 09:34 AM
What does information within the SCB registers tell you about the reason for the hard fault? Use a fault analyzer if needed.
The calls to HAL_*_DeInit aren't as intended. These should be called using the same global handles that were used in the HAL_*_Init calls. Unclear if this is the source.
2023-06-28 09:40 AM
You probably need to map system memory to 0x00000000 via SYSCFG->CFGR1. And you probably need to set the VTOR back to 0 as well (SCB->VTOR).
2023-06-28 05:38 PM
@DAUSILI wrote:
/* Clear Interrupt Enable Register & Interrupt Pending Register */
for (i = 0; i < 5; i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
The M0+ has only 1 ICER and ICPR register, not 5. So this code is writing to registers that don't exist. That's probably the cause of the hardfault.
2023-06-29 07:36 AM
Hello Jeff,
the cause of the malfunction was due to a wrong VTOR alignment.
The main memory was mapped at 0x00000000, so before jumping to system memory I correct the VTOR value in this way:
#define SYSTEM_MEMORY_ADDR 0x1FFF0000
__ISB();
SCB->VTOR = SYSTEM_MEMORY_ADDR;
__DSB();
Thank you,
Daniele
2023-06-29 01:21 PM
This is incorrect and quite different from the original code:
f = (void (*)(void)) BOOTLOADER_ENTRY_ADDR;
See my post in the bootloader thread for a correct and simpler version