Arm Mbed OS support forum

Jump to DFU bootloader Mbed

I have been setting up a method to jump to the DFU bootloader for an STM32F405RG with the code provided in the link below (which I have received from other mbed forum posts) and the addresses should work for any STM32F4 chip based on what I have read. I have built the main.cpp and put it in the dfu-util folder for upload, but when I check for dfu devices in the command prompt, the chip doesn’t seem to go into DFU mode. There may also be a missing config in my custom_targets.json so please point anything out that causes the bootload code to not work.

My code can be found in this link: GitHub - DheerN/stm-testing

Any solutions?

I used the approach here to solve this: How do you jump to the bootloader (DFU mode) in software on the STM32 F072? - Stack Overflow

i.e. set a flag on application and reset, then check it in SystemInit(), where the peripherals are not yet initialized. The problem with jumping from application is that some peripherals (e.g. clocks) are initialized in such a way, where it gets pretty hard to deinit everything.

Hello @boraozgen ,

Thanks for the prompt reply. I have been using the following code to essentially do the same but the device doesn’t go into DFU mode.

#include "mbed.h"


void enterDFU(){

__asm ("LDR     R0, =0x40023844");// RCC_APB2ENR
__asm ("LDR     R1, =0x00004000");// ENABLE SYSCFG CLOCK
__asm ("STR     R1, [R0, #0]");

__asm ("LDR     R0, =0x40013800");// remap ROM at zero
__asm ("LDR     R1, =0x00000001");// SYSCFG_MEMRMP
__asm ("STR     R1, [R0, #0]");

__asm ("LDR     R0, =0x1FFF0000");// ROM BASE
__asm ("LDR     SP,[R0, #0]");    // SP @ +0
__asm ("LDR     R0,[R0, #4]");    // PC @ +4

__asm ("BX      R0");             // Jump to Bootloader
}


int main() {
    DigitalOut usb_dp_pin(USB_OTG_FS_DP, 1) ;
    wait(0.01);
    usb_dp_pin=0;
   
    enterDFU();  
}

I then place the compiled binary into the dfu-util folder and run the following which checks for devices in DFU.

dfu-util -l

I get no response after this. Do you have any solutions to solve this recurring issue? I am using MBED OS 5 by the way.

As I said this you should do the jump before main(). Check the SystemInit() function for STM32 targets.

Hello @boraozgen ,

Would you mind elaborating what needs to be done with the SystemInit() function? I don’t exactly understand the code in the link you provided. My apologies for being slightly slow.

Thanks.

This is what do to set the flag and reset:

*((unsigned long *)0x2001FFF0) = 0xDEADBEEF;

// Reset the processor
NVIC_SystemReset();

In SystemInit() I do the check and jump like this:

    // Check if a software jump to the bootloader section is required
    static void (*SysMemBootJump)(void);

    // Check if the bootloader flag is set
    if (*((unsigned long *)0x2001FFF0) == 0xDEADBEEF)
    {
        // Reset our trigger
        *((unsigned long *)0x2001FFF0) = 0xCAFECAFE;
        // Set the SP to the default value
        __set_MSP(*(volatile uint32_t *)0x00000000);
        // Set the PC to the System Memory reset vector (+4)
        SysMemBootJump = (void (*)(void))(*((uint32_t *)0x1FFF0004));
        // Jump to bootloader
        SysMemBootJump();
    }

Modify the flag address & value to your preference. Also the jump address might differ between STM32 models, better check the bootloader docs/datasheet for that.

Hello @boraozgen ,

Thanks for that information. I tried doing that after modifying the addresses correctly, but it still doesn’t enter DFU through the command line. I also want to use mbed os 5 to perform this and I am using a custom target for the F405 board that I created myself. Do you think there is something I’m missing in the target or in mbed that is causing this?

Thanks.

I believe I can’t help you further. The previous code is what I use. You have to make sure you jump into the right address before any peripherals are initialized.