Jump to sysmem bootloader on STM32L476. How to perform correctly?
I need to jump to DFU from software (BOOT0 pin not available in board design) on STM32L476RG. I'm following the process outlined in https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/ - but added the memory barriers that seems to be critical for STM32L4 - from https://community.st.com/s/question/0D50X00009XkeeWSAR/stm32l476rg-jump-to-bootloader-from-software
Two people seemed to have success with that receipe on STM32L476, but I don't end up in the sysmem DFU bootloader - just get thrown back into my application.
Here is the code that I got:
#define SYSMEM_START 0x1FFF0000
void check_jump_bootloader(void)
{
// Define our function pointer
volatile void (*SysMemBootJump)(void);
if (bootloader_flag == BOOTLOADER_FLAG_SET) {
bootloader_flag = BOOTLOADER_FLAG_RESET;
#if 1
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
#endif
#if 1
__disable_irq();
#endif
#if 1
__DSB();
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
/* Remap is not visible at once. */
__DSB();
__ISB();
#endif
// System Memory reset vector is one word after SYSMEM_START
SysMemBootJump = (void (*)(void)) ((uint32_t *)(SYSMEM_START + 4));
// Set stack pointer value
//__IO uint32_t sp = *(__IO uint32_t*)SYSMEM_START;
__set_MSP(*(__IO uint32_t*)SYSMEM_START);
// jump
SysMemBootJump();
while (1);
}
}This function is called as the first thing in SystemInit. I am testing this on a Nucleo-L476 development board for now.
Using gdb to break in check_jump_bootloader() , using "monitor rest halt" to reset the CPU, and then setting the bootloader flag at breakpoint before stepping through the jump code.
Then I can see that the microcontroller seems to reset instantly upon hitting the SysMemBootJump(), and goes back to the start of my application.
If I remove the __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH() call then I instead get a hardfault.
I can also see this reset loop behavior when triggering bootloader from a GPIO pin, without gdb connected.
What am I doing wrong?
I tried removing the interrupt disabling and the systick reset (should not be needed as I'm coming through a reset?) - but no change.
Compiler is GCC 9.1.0. Using a Makefile generated by STM32CubeMx on a simple project (only GPIO pheripherals, LSE clock). Using STM32Cube_FW_L4_V1.13.0
