3
\$\begingroup\$

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?

\$\endgroup\$
3
\$\begingroup\$

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();
}
\$\endgroup\$
0
\$\begingroup\$

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

... if your program does definitely not access the "low" memory. Don't forget to remap the interrupt table.

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?

If you are really using the USART pins (not USB serial emulation): Opening/closing the serial port should only effect the control lines, not the data lines. In most cases the control lines will not even be connected to the CPU.

\$\endgroup\$
  • \$\begingroup\$ It looks like something related to interrupts or other configs indeed. The function works if it's called right at the start of main(). \$\endgroup\$ – MarcelNubi Jun 21 '17 at 23:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.