3

I am trying to immediately jump to the DFU bootloader via software on the STM32F405RG, but instead it is doing a software reset and the RCC_FLAG_SFTRST flag is thrown. The program continues to repeatedly execute the code for jumping to bootloader and finally stays in bootloader mode after multiple seconds. I experienced success with entering bootloader mode on the first try if interrupts are disabled. However, I cannot upload code while in DFU mode since it requires interrupts to be enabled. I am unsure what is causing the bootloader to jump back to the application and was hoping to get assistance on this. Below is the code for jumping to bootloader, which is called immediately after Init_HAL() under main.

void JumpToBootloader(void) {


    void (*SysMemBootJump)(void);
   
    volatile uint32_t addr = 0x1FFF0000;
  

    HAL_RCC_DeInit();
    HAL_DeInit();
    
    /**
     * Step: Disable systick timer and reset it to default values
     */

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

    
    /**
     * Step: Interrupts are not disabled since they are needed for DFU mode
     */
    // __disable_irq();
    
    /**
     * Step: Remap system memory to address 0x0000 0000 in address space
     *       For each family registers may be different. 
     *       Check reference manual for each family.
     *
     *       For STM32F4xx, MEMRMP register in SYSCFG is used (bits[1:0])
     *       For STM32F0xx, CFGR1 register in SYSCFG is used (bits[1:0])
     *       For others, check family reference manual
     */
    
    __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();    //Call HAL macro to do this for you
    
    /**
     * Step: Set jump memory location for system memory
     *       Use address with 4 bytes offset which specifies jump location where program starts
     */
    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
    
    /**
     * 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
     */
    __set_MSP(*(uint32_t *)addr);
    
    /**
     * Step: Actually call our function to jump to set location
     *       This will start system memory execution
     */
    SysMemBootJump();
    
}

1 Answers1

0

Taking a look at the Application Note AN2606, Rev.55, chapter 28 STM32F40xxx/41xxx devices bootloader, page 127, one can see that the first step is called "System Reset". The DFU is not designed to be executed from your application, but to be called according to the bootloader selection after a system reset. Before you are even entering the main function of your application, a few steps are already executed to prepare the device. These steps may be different for the DFU. Calling the DFU from an unexpected system state can lead to undefined behaviour.

The best way to enter the DFU is to latch the BOOT0 pin high and then perform a system reset either by software reset, or by IWDG.

Another potential problem can arise from the HSE, which has to be provided externally, however since you stated that the DFU does eventually work, this seems unlikely.

Menroka
  • 19
  • 5