Electronic – STM32F091 Jump to Bootloader from application

bootloaderstm32stm32f0

I'm trying to implement a jump to the STM32F091 USART1 bootloader from my application.

I'm using the following function(based on https://community.st.com/thread/40238-stm32l476rg-jump-to-bootloader-from-software):

void SB_SystemBootloaderJump()
{
    typedef void (*pFunction)(void);
    pFunction JumpToApplication;

    HAL_RCC_DeInit();

    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;

    /**
     * Step: Disable all interrupts
     */
    __disable_irq();

    /* ARM Cortex-M Programming Guide to Memory Barrier Instructions.*/
    __DSB();

//  __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH()
//  ;

//  /* Remap is bot visible at once. Execute some unrelated command! */
//  __DSB();
//  __ISB();

    JumpToApplication = (void (*)(void)) (*((uint32_t *) ((0x1FFFD800 + 4))));

    /* Initialize user application's Stack Pointer */
    __set_MSP(*(__IO uint32_t*) 0x1FFFD800);

    JumpToApplication();
}

From APP Note AN2606: System Memory address as in picture: https://i.imgur.com/nVcgoBg.png

From SWD Utility, memory contents at System Memory: https://i.imgur.com/PeepkrX.png

From Debugger, SP and Reset handler as picture: https://i.imgur.com/PagQng0.png

Program execution up to breakpoint at Bootloader address : https://i.imgur.com/koKfObe.png

Considering:
A – Using a jumper to VCC on BOOT0 pin, I can successfully access the system bootloader via STM32 Flash Loader Demo. The same is not true if I jump to the bootloader from my app.
B – I'm using a FTDI FT230x USBxSerial Bridge.

Questions:

1 – Since I'm using the absolute system memory address, there is no need to use __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(). Correct?

2 – Am I missing something on this function?

3 – Is there a timeout between the bootloader starting and receiving the "0x7F" byte on USART1?

4 – Will opening/closing the serial port affect the bootloader? Do I have to reset the MCU if I close the serial port and open it again?

Best Answer

The problem was with the USART1 peripheral state. The USART1 config register values were being carried to the bootloader execution, possibly causing trouble for the proprietary bootloader. Solution was to reset USART1 via RCC_APB2RSTR.

The function now is:

void SB_SystemBootloaderJump()
{
    typedef void (*pFunction)(void);
    pFunction JumpToApplication;

    __HAL_RCC_USART1_FORCE_RESET();
    HAL_Delay(5);
    __HAL_RCC_USART1_RELEASE_RESET();
    HAL_Delay(5);

    HAL_RCC_DeInit();

    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;

    /**
     * Step: Disable all interrupts
     */
    __disable_irq();

    /* ARM Cortex-M Programming Guide to Memory Barrier Instructions.*/
    __DSB();

    __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH()
    ;

    /* Remap is bot visible at once. Execute some unrelated command! */
    __DSB();
    __ISB();

    JumpToApplication = (void (*)(void)) (*((uint32_t *) ((0x1FFFD800 + 4))));

    /* Initialize user application's Stack Pointer */
    __set_MSP(*(__IO uint32_t*) 0x1FFFD800);

    JumpToApplication();
}