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.
DFU Mode from running code?
Moderators: RoccoMarco, barthess
- 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?
Hi,
I don't know, the question should be directed to ST I think.
Giovanni
I don't know, the question should be directed to ST I think.
Giovanni
Re: DFU Mode from running code?
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....
-
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
Re: DFU Mode from running code?
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.
If I decide to proceed on further, I will shoot a question over to the ST boards.
Re: DFU Mode from running code?
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:
I had some issues with USB re-enumeration, so my full code for jumping into DFU is:
Hope this helps,
Markus
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
- 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?
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
2) in ChibiOS I add custom code all the way on top of _crt0_entry
and in a separate S file I have
git commits https://github.com/rusefi/ChibiOS/commi ... ebcca94e81
and https://github.com/rusefi/rusefi/commit ... 675ef3e8cb
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
- 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?
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.
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.
Who is online
Users browsing this forum: No registered users and 16 guests