Showing results for 
Search instead for 
Did you mean: 

How to restart into bootloader (with DFU).

typedef void resetvec(void);
void cmd_jbl(BaseSequentialStream *chp, int argc, char **argv) // reboot to bootloader
 unsigned int t;
 resetvec *fun; 
 fun = ((uint32_t *)0x1fffc800)[1]; 
#define GPIOA_OTG_FS_DP 12
 // First disconnect the USB bus. 
#if 0
 usbDisconnectBus(serusbcfg.usbp); // this calls usb_lld_disconnect_bus(usbp), which expands to 
 // palClearPad(GPIOA, GPIOA_OTG_FS_DP); ((usbp)->otg->GCCFG &= ~GCCFG_VBUSBSEN)
 // now disable interrupts. We're on our own now! no sleeps etc.
 delay_us (1000000);
 //chThdSleepMilliseconds(1000); // disconnect USB
 t = RCC->CR;
 t &= 0x0000ff00; // keep the cal. 
 t |= 0x83; // reset trim, run on HSI. 
 RCC->CR = t;
 RCC->CFGR = 0;
 RCC->CIR = 0;
 RCC->APB2RSTR = 0xffffffff;
 RCC->APB1RSTR = 0xffffffff;
 RCC->AHBENR = 0x00000014;
 RCC->APB2ENR = 0x0;
 RCC->APB1ENR = 0x0;
 RCC->BDCR = 0x018;
 RCC->CSR = 0;
 RCC->CFGR2 = 0;
 RCC->CFGR3 = 0;
 RCC->CR2 = 0x80; // keep the trim at neutral the cal bits are RO.
 PWR->CR = 0;
 PWR->CSR = 0;
 // I think I have everything in reset state. Now do what needs to be
 // done to reset stuff.
 RCC->APB2ENR = 1; // enable sysconfig. 
 SYSCFG->CFGR1 = 1; // system memory is now mapped at zero. 
 // NVIC_SystemReset();
 (*fun) () ;
 while (1) {
  __asm__ ("nop");

I don't know how to type above the "code snippet" I posted (I tried the obvious, click there). (And I didn't enter those empty lines in there either. ).

I'm trying to implement a command inside my STM32 to jump to the bootloader to allow it to get a fresh firmware binary. Currently I have to press the boot button and then reset to get it into boot loader mode.

In theory that's simple: jump to the bootloader. In practice, you need to reset the CPU to most of the CPU to reset state before jumping to the bootloader. The above code snippet is how far I've gotten, and when I try to disable the USB further than what's now enabled, the system crashes before i get to the whole reset stuff.

I have the impression that it does run the bootloader, and I'd be able to use serial to flash the device, however I want to have USB as the only connection to the device...

After the jump to bootloader, I see a new device on the USB port, but then it refuses to enumerate.

usb 3-11: new full-speed USB device number 66 using xhci_hcd

device not accepting address 68, error -71

The "published" method to do this is to modify the bootcode and jump to the bootloader from the startup code. That seems to work for others (I haven't tried it) but I don't like that option because it requires me to modify core code in my little os: ChibiOS. Of course it's open source and I CAN do it, but that code is not "mine" to modify. My code would then only work with a modified version and I don't like that.

So what could be going wrong in that the USB enumeration from the bootloader isn't working?


What STM32? They make hundreds of parts in dozens of families at this point, you're going to need to be specific.

Important not to call with interrupts disabled, or from interrupt, callback, or "user" mode.

Interrupts should be disabled at a peripheral level, not the system level.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III

"Jump to bootloader" is an extremely frequent topic. Application note on this is long due.

Perhaps, but people don't read/understand anything these days, we'll still be answering these things in a decade from now.

More chance to monetize a YouTube video I suppose, I'm on the wrong platform.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Sorry. STM32F072 is the current target.

What do you suggest I don't call with interrupts disabled? The Jump to the system memory? I would think that that piece of code expects to be called with "interrupts disabled". Or rather, I would expect a CPU to start up that way. To be honest that's a "basic knowledge" thingy that I did not verify in a datasheet.

I did omit setting the stack pointer to the precise place that the system memory specifies. I guess I should fix that before I complain again. 🙂

OK. I added:

  asm ( " msr msp, %0" : : "r" (SYSTEM_MEM[0]) );
  asm ( " msr psp, %0" : : "r" (SYSTEM_MEM[0]) );

and still get the USB-not-working-right behaviour of before.