DFU Mode from running code?

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

Rick Burnett
Posts: 150
Joined: Tue Jan 08, 2013 2:20 pm

DFU Mode from running code?

Postby Rick Burnett » Mon Jan 15, 2018 8:18 am

Is it possible to exit out of my application into DFU mode once I am executing my code?

Right now I have a button on my circuit that you have to hold down when powering up. I'd rather just make an option through my UI while running to go into DFU mode.

Am I am able to do this? Using the STM32F427 chip.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: DFU Mode from running code?

Postby Giovanni » Mon Jan 15, 2018 8:25 am

Hi,

I don't know, the question should be directed to ST I think.

Giovanni

rew
Posts: 380
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 13 times

Re: DFU Mode from running code?

Postby rew » Sat Jan 20, 2018 8:47 pm

The DFU firmware is quite "primitive" in that it expects almost everything in fresh-from-reset state. So I would imagine that you disable interrupts and then use RCC to reset most modules. Then configure system memory into boot-space, load stack pointer from 0x0000 and then PC from 0x0004. That should do it. But things are likely to have a few snags....

Rick Burnett
Posts: 150
Joined: Tue Jan 08, 2013 2:20 pm

Re: DFU Mode from running code?

Postby Rick Burnett » Sun Jan 21, 2018 10:31 pm

Thanks for the information, only reason I asked here was if anyone had done this. Makes sense that the way it is probably written is to have a small footprint as well, so expectations of the processor state make sense.

If I decide to proceed on further, I will shoot a question over to the ST boards.

MarkusS
Posts: 14
Joined: Tue Mar 13, 2012 6:52 pm
Has thanked: 1 time

Re: DFU Mode from running code?

Postby MarkusS » Tue Jan 30, 2018 10:36 pm

I tried this before and failed. I am not sure what I did wrong, but I was not able to get the DFU mode running after ChibiOS initialized the uC.
My solution was a combination of hard and software. I used a 1 MOhm pull-down resistor for the BOOT0 pin and added a 2.2uF cap in parallel. And I also connected another GPIO pin (PB7) to the BOOT0 pin. Now, if I want to jump into the DFU mode, I set the GPIO pin high, wait a few ms until the cap is charged and then do a reset...

Code:

Code: Select all

palSetPadMode(GPIOB, 7, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(GPIOB, 7);
chThdSleepMilliseconds(500); // charge cap up so that BOOT0 stays high during reset...

palSetPadMode(GPIOB, 7, PAL_MODE_INPUT_PULLUP); // so that we don't discharge the cap on reset
NVIC_SystemReset();


I had some issues with USB re-enumeration, so my full code for jumping into DFU is:

Code: Select all

palSetPadMode(GPIOB, 7, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(GPIOB, 7);
chThdSleepMilliseconds(500); // charge C20 up so that BOOT0 stays high during reset...

usbStop(serusbcfg.usbp);
palSetPadMode(GPIOA, GPIOA_OTG_FS_DP, PAL_MODE_OUTPUT_OPENDRAIN); //GPIOA_OTG_FS_DP is PA12 = USB DP
usbDisconnectBus(serusbcfg.usbp); // this calls usb_lld_disconnect_bus(usbp), which expands to
                                                     // palClearPad(GPIOA, GPIOA_OTG_FS_DP); ((usbp)->otg->GCCFG &= ~GCCFG_VBUSBSEN)
chThdSleepMilliseconds(1000); // disconnect USB

palSetPadMode(GPIOB, 7, PAL_MODE_INPUT_PULLUP); // so that we don't discharge the cap on reset
NVIC_SystemReset();


Hope this helps,

Markus

User avatar
russian
Posts: 364
Joined: Mon Oct 29, 2012 3:17 am
Location: Jersey City, USA
Has thanked: 16 times
Been thanked: 14 times

Re: DFU Mode from running code?

Postby russian » Sat Jul 27, 2019 3:29 am

Bump. Did anyone have success with software DFU jump from ChibiOS?
http://rusefi.com/ - electronic fuel injection

User avatar
russian
Posts: 364
Joined: Mon Oct 29, 2012 3:17 am
Location: Jersey City, USA
Has thanked: 16 times
Been thanked: 14 times

Re: DFU Mode from running code?

Postby russian » Sun Jul 28, 2019 5:38 pm

I got this working in my project.

This was based on https://community.st.com/s/question/0D5 ... -a-program

1) in C code I remember magic value in SRAM & reboot

Code: Select all

   // leave DFU breadcrumb which assmebly startup code would check, see [rusefi][DFU] section in assembly code
   *((unsigned long *)0x2001FFF0) = 0xDEADBEEF; // End of RAM
   // and now reboot
   NVIC_SystemReset();


2) in ChibiOS I add custom code all the way on top of _crt0_entry

Code: Select all

                .global _crt0_entry
_crt0_entry:
// [rusefi][startup][start]
   bl rusEfiAsboluteStartupMethod // jump to 'rusEfiStartupMethod'
   .global rusEfiAsboluteStartupMethodReturnPoint
rusEfiAsboluteStartupMethodReturnPoint: // custom rusEfi would go back here
// [rusefi][startup][end]
                /* Interrupts are globally masked initially.*/
                cpsid   i



and in a separate S file I have

Code: Select all

/**
 * @file rusEfiStartup.S
 * rusEfi startup assembly
 *
 * We have ChibiOS '_crt0_entry' jumping here and then we jump back.
 * There is probably no stack at this point to invoke a method.
 */

// todo: I have no idea which lines are doing what
// todo: one of these is resolving 'Error: lo register required -- `ldr SP,[R0,#0]'' :)
    .syntax unified
   .cpu    cortex-m3
   .thumb
   .align  2
   .thumb_func
// end of 'I have no idea'

   .global rusEfiAsboluteStartupMethod
rusEfiAsboluteStartupMethod:
// [rusefi][DFU][start]
// Clive Two.Zero is the God of ST community forum
// Device specific, if in doubt RTFM
LDR R0, =0x2001FFF0 // End of SRAM for your CPU
LDR R1, =0xDEADBEEF // magic value
LDR R2, [R0, #0]
STR R0, [R0, #0] // Invalidate
CMP R2, R1
BEQ UseDFU
   // DFU bootloader not needed, jump back to normal ChibiOS startup
   bl   rusEfiAsboluteStartupMethodReturnPoint
UseDFU:
   // AN2606 Application note
   // STM32 microcontroller system memory boot mode
LDR R0, =0x40023844 // RCC_APB2ENR
LDR R1, =0x00004000 // ENABLE SYSCFG CLOCK
STR R1, [R0, #0]
LDR R0, =0x40013800 // SYSCFG_MEMRMP
LDR R1, =0x00000001 // MAP ROM AT ZERO
STR R1, [R0, #0]
LDR R0, =0x1FFF0000 // ROM BASE
LDR SP,[R0, #0] // SP @ +0
LDR R0,[R0, #4] // PC @ +4
BX R0 // this jumps to DFU bootloader
   // I believe we are never executing this line
// [rusefi][DFU][end]



git commits https://github.com/rusefi/ChibiOS/commi ... ebcca94e81
and https://github.com/rusefi/rusefi/commit ... 675ef3e8cb
http://rusefi.com/ - electronic fuel injection

User avatar
kimmoli
Posts: 27
Joined: Sat Oct 01, 2016 8:02 pm
Has thanked: 11 times
Been thanked: 9 times
Contact:

Re: DFU Mode from running code?

Postby kimmoli » Sat Feb 01, 2020 10:51 pm

Thanks for sharing. works like charm.

Except, if i enable watchdog in the code, it hangs on first boot in the wdgStart() after flashing over DFU.
Watchdog works fine after re-flashing via stlink.

Also it boots ok if not enabling watchdog.

Haven't yet traced where it actually hangs.


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 16 guests