Jumping to bootloader from user code in STM32L476
I am trying to implement a procedure to update firmware in a STM32L476 by jumping to the bootloader from user code. I am able to connect Boot0 to 3,3V and enter the bootloader just fine. But trying to jump there from user code seems to be giving some problems.
It seems that when I execute my code, the device does a soft reset, and just restarts the application. I believe it may have something to do with the dual bank management. Even when I jump to the bootloader, I think it is checking both ram locations and finding valid code, thus not staying in the bootloader. Here is my code:
void JumpToBootloader(void)
{
void (*SysMemBootJump)(void);
// Step: Set system memory address
// See AN2606 rev 38, Table 118
volatile uint32_t addr = 0x1FFF0000;
// Step: Disable RCC, set it to default (after reset) settings
// Internal clock, no PLL, etc.
HAL_RCC_DeInit();
// Step: Disable systick timer and reset it to default values
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Step: Disable all interrupts
__disable_irq();
// Step: ARM Cortex-M Programming Guide to Memory Barrier Instructions
__DSB();
// Step: Remap system memory to address 0x0000 0000 in address space
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); // Call HAL macro to do this for you
// Step: Remap is not visible at once. Execute some unrelated command! */
__DSB();
__ISB();
// Step: Set jump memory location for system memory
// Use address with 4 bytes offset which specifies jump location where program starts
uint32_t a = 0x1FFF0000 + 4;
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(a)));
// Step: Set main stack pointer.
// This step must be done last otherwise local variables in this function
// don't have proper value since stack pointer is located on different position
//;
// Set direct address location which specifies stack pointer in SRAM location
uint32_t p = *(uint32_t *)0x1FFF0000;
__set_MSP(p);
// Step: Actually call our function to jump to set location
// This will start system memory execution
SysMemBootJump();
while(1);
// Step: Use STM32CubeProgrammer or custom application to update firmware.
}
For testing purposes, I am just calling this function right after main() starts. One other thing I will need to be able to do is activate a GPIO to enable my RS232 chip that is connected to USART2. So I need that G?PIO to stay in the state I put it in instead of the reset state, is this possible
