cancel
Showing results for 
Search instead for 
Did you mean: 

Jump to USB DFU Bootloader in startup code on STM32F042

ethanzonca
Associate
Posted on February 21, 2015 at 18:11

I'm running a STM32F04 and want to jump to the USB DFU bootloader from user code. As recommended in other posts, I set a magic bit in SRAM, issue a soft reset, check for the magic value and branch to the bootloader if the magic value exists in the startup code.

My problem is that I branch to the bootloader but the F042 doesn't show up as a USB DFU device, it just seems to hang. I'm confident I have the correct memory addresses and I can't find any issues with my approach. Any ideas? Thanks.

Reset_Handler:
/* Bootloader jumping */
ldr r0, =0x200017F0 
/* address of magic token */
ldr r1, =0xDEADBEEF 
/* magic token */
ldr r2, [r0, #0] 
/* load data from magic address */
str r0, [r0, #0] 
/* zero data at magic address so we don't get stuck here */
cmp r2, r1 
/* compare data at magic address to magic token */
beq Reboot_Loader 
/* jump to bootloader if token match */
/* End bootloader jumping */
ldr r0, =_estack
mov sp, r0 
/* set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit

// On reset, SP=value at address 0x0
ldr r0, =0x00000000
ldr r0, [r0, #0]
mov sp, r0
ldr r0, =0x1FFFC800 
/* Address of bootloader on f042 from CD00167594 pg 15 table 3 */
// Branch to bootloader
ldr r0, [r0, #4]
bx r0

#bootloader #dfu #stm32f0 #stm32f042-bootloader-dfu
27 REPLIES 27
Posted on February 22, 2015 at 00:20

Based on my reading of RM0091 Rev 7, I'd do this

Reboot_Loader PROC
EXPORT Reboot_Loader
LDR R0, =0x40021018 ; RCC_APB2ENR (+0x18)
LDR R1, =0x00000001 ; ENABLE SYSCFG CLOCK
STR R1, [R0, #0]
LDR R0, =0x40010000 ; SYSCFG_CFGR1 (+0x00)
LDR R1, =0x00000001 ; MAP ROM AT ZERO
STR R1, [R0, #0]
; LDR R0, =0x1FFFEC00 ; ROM BASE (STM32F03x)
LDR R0, =0x1FFFC400 ; ROM BASE (STM32F04x)
; LDR R0, =0x1FFFEC00 ; ROM BASE (STM32F05x)
; LDR R0, =0x1FFFC800 ; ROM BASE (STM32F07x)
; LDR R0, =0x1FFFD800 ; ROM BASE (STM32F09x)
LDR R1, [R0, #0] ; SP @ +0
MOV SP, R1
LDR R0, [R0, #4] ; PC @ +4
BX R0
ENDP ; sourcer32@gmail.com

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 22, 2015 at 00:35

Page 84 (AN2606 Rev 20) is the salient one for your part

http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf

The address is 0x1FFFC400, not C800, loading the stack pointer from ZERO will load the USER FLASH's stack pointer, not the ROM's stack pointer, when the USER memory is mapped there.

Having mapped the ROM at ZERO, I could just load R0 with ZERO instead of the normal address it resides at. This would probably be a simpler approach, but the actual address serves as a good illustration, and one could evaluate if the mapping is, or is not required.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 22, 2015 at 03:22

More generically

Reboot_Loader PROC
EXPORT Reboot_Loader
LDR R0, =0x40021018 ; RCC_APB2ENR (+0x18)
MOVS R1, #1 
STR R1, [R0, #0] ; ENABLE SYSCFG CLOCK (1)
LDR R0, =0x40010000 ; SYSCFG_CFGR1 (+0x00)
STR R1, [R0, #0] ; MAP ROM AT ZERO (1)
MOVS R1, #0 ; ADDRESS OF ZERO
LDR R0, [R1, #0] ; SP @ +0
MOV SP, R0
LDR R0, [R1, #4] ; PC @ +4
BX R0
ENDP ; sourcer32@gmail.com

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Denis Krasutski
Associate III
Posted on May 15, 2015 at 18:52

Hello Clive1,

I am trying use your code but I have just reboot device.

My steps:

1. Set magic number to memory

2. call HAL_NVIC_SystemReset

3. In startup I comparing memory.

4. if i have equals, I make ''BEQ  Reboot_Loader''

But after entry to Reboot_Loader after some time my firmware will run.

But When  I memory erase, my device detected in usb dfu mode.(it is means USB work).

Can I get another way for start DFU mode?

Posted on May 15, 2015 at 19:08

If the System Loader uses a Watchdog Reset to start over it will fall back to your code, based on the state of the BOOTx pins.

I'm not using F0 parts so haven't invested much time in them. If you removed the invalidation code, ie where it writes a non-magic number, and the value stays in RAM, it will keep resetting and handing control over to the System Loader. I've avoided this as it might create a loop it can't escape.

The other alternatives are to control the BOOTx pins externally, or implement your own DFU code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Denis Krasutski
Associate III
Posted on May 18, 2015 at 09:26

Thanks for answer,

-My project dont use Watchdog.

-When I try run Reboot_Loader in reset_handler I also got bad result

But I found next solution: erase FLASH memory and reboot MCU.

Best Regards,

 

Krasutski Denis
vector950
Associate II
Posted on May 20, 2015 at 09:00

I have the same problem on STM32L051, when I use magic word and reboot MCU. It go to ResetHandler and run Reboot_Loader. But after that it goes through reset and ST bootloader does not work. Infinity loop with Reboot_Loader also does not help, it is just infinity reset. How I can resolve this issue?

Posted on May 20, 2015 at 13:45

Well it's probably because the code in this thread targets the F0 not L0 parts, which likely have slightly different peripheral registers, and Boot ROM address.

https://community.st.com/0D50X00009XkgUkSAJ

 

Edit: Fixed the DEAD LINK, original post from 20-May-2015
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 20, 2015 at 14:04

-My project don't use Watchdog.

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