cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 jump to bootloader without boot0 pulled up

Posted on November 26, 2015 at 14:19

Hello there,

I am working on an application now, where I need to send a command to the mcu through USB in order to reset the mcu and jump to system memory bootloader. On my board boot1 is shorted to ground, that means if I reset the mcu with boot1 pulled up, the system starts from bootloader. User however wont have access to boot1 phisically, so before watchdog reset I need to set boot1 in software somehow. Is that possible? I would apreciate all help!
11 REPLIES 11
Posted on November 26, 2015 at 14:27

It doesn't quite work that way. You'd need to set a marker in RAM, let the Watchdog expire, and catch that early in your ResetHandler, and vector off into the System ROM.

https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/jumping%20to%20the%20bootloader%20via%20software%20does%20not%20permit%20dfu%20mode&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146...

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

So if I understand correctly, I have to do something before I expire the watchdog and do something in the reset interrupt routine? How can I get the reset interrupt routine function in HAL?

Posted on November 26, 2015 at 15:58

I presume the HAL still uses startup_stm32xxx.s? You add code there to react to the reset which recognizes a setting you have left in an agreed location in RAM. Ideally one outside of the linker's scope

This is for the F1 but provides more context to the method.

/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Threaded.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Jump%20to%20internal%20bootloader&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=1653

To refactor for you

In application.c
// 1FFF0000 -> 2000xxxx -> SP
// 1FFF0004 -> 1FFFxxxx -> PC
printf(''Entering Boot Loader..

'');
*((unsigned long *)0x2001FFF0) = 0xDEADBEEF; // 128KB STM32F4xx
// NVIC_GenerateSystemReset(); // Explicitly Reset (SPL/CMSIS)
while(1); // Wait for Watchdog to fire
In startup.s
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =0x2001FFF0 ; Magic Location
LDR R1, =0xDEADBEEF
LDR R2, [R0, #0]
STR R0, [R0, #0] ; Invalidate
CMP R2, R1
BEQ Reboot_Loader
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
Reboot_Loader PROC
EXPORT Reboot_Loader
LDR R0, =0x40023844 ; RCC_APB2ENR
LDR R1, =0x00004000 ; enable SYSCFG clock
STR R1, [R0, #0]
LDR R0, =0x40013800 ; SYSCFG_MEMRMP
LDR R1, =0x00000001 ; remap ROM at zero
STR R1, [R0, #0]
LDR R0, =0x1FFF0000 ; load ROM base
LDR SP,[R0, #0] ; assign main stack pointer
LDR R0,[R0, #4] ; load bootloader address
BX R0
ENDP

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

Yes, In my project there is a file startup_stm32f407xx.s

I think I understand the overal concept now. I need to place some value in ram and check it when reset in startup code. But what does this mean?

// 1FFF0000 -> 2000xxxx -> SP
// 1FFF0004 -> 1FFFxxxx -> PC

Do you mean to save a value 1fff0000 to the address 2000xxxx? And what is SP and PC? This line saves the value right?

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

The code provided for startup.s is supposed to be placed at the beginning of the file? Also, I need to change the addresses for my MCU that is 1 MB flash right, or did you do it already?
Posted on November 26, 2015 at 17:59

You're using a Cortex-M4 processor, the two initial vector entries contain a Stack Pointer (SP) and a Program Counter (PC). The SP will be pointing into the RAM somewhere, and the PC will be pointing to some code deeper into the ROM image. When BOOT0 is High, the memory at 0x1FFF0000 maps at zero within the address space of the processor, as well as it's normal address. The Reboot_Loader effects this transfer of control, with the memory mapping/shadowing in this fashion.

Yes, it writes a 32-bit word into the back end of the RAM which starts at 0x20000000. A pointer with an explicit address.

Not sure what the size of the FLASH has to do with anything here, it's situated at 0x08000000

You are placing the code in the RESET HANDLER, ie what it does immediate as the processor resets. Basically : Look I have a magic constant, redirect execution off into the ROM image, otherwise start as normal.

http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439b/DDI0439B_cortex_m4_r0p0_trm.pdf

http://www.amazon.com/Definitive-Cortex%C2%AE-M3-Cortex%C2%AE-M4-Processors-Edition/dp/0124080820

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

Thank you for the links and explanation. I will try this tommorow morning.

Posted on November 26, 2015 at 20:15

I tried to insert the assembler code now, but all the symbols (I dont understand them as well) are unrocognised, like PROC, EXPORT, IMPORT etc.

This is my startup file: https://pastebin.com/LuQvc3H0

There is a label Reset_Handler already. Does the additional content replaces this ''function'' address? How to make the compiller understand the symbols?

Posted on November 26, 2015 at 23:57

That would be because they are Keil assembler directives

.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler: 
/* <<<< ADD CODE HERE TO CHECK AND BRANCH TO REBOOT_HANDLER <<<< */
 LDR R0, =0x2001FFF0 ; Magic Location
 LDR R1, =0xDEADBEEF
 LDR R2, [R0, #0]
 STR R0, [R0, #0] ; Invalidate
 CMP R2, R1
 BEQ Reboot_Loader

ldr sp, =_estack /* set stack pointer */

After the Reset Handler
Reboot_Loader:
LDR R0, =0x40023844 ; RCC_APB2ENR
LDR R1, =0x00004000 ; enable SYSCFG clock
STR R1, [R0, #0]
LDR R0, =0x40013800 ; SYSCFG_MEMRMP
LDR R1, =0x00000001 ; remap ROM at zero
STR R1, [R0, #0]
LDR R0, =0x1FFF0000 ; load ROM base
LDR SP,[R0, #0] ; assign main stack pointer
LDR R0,[R0, #4] ; load bootloader address
BX R0

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

Clive, your help is priceless! Thank you very much, I managed to get it working 🙂

For now, I think it is great. However, after i slept with thinking about this application I think i found a flaw in it:

In order to give the possibility of jumping to bootloader for the user, the application loaded has to be valid. If one puts garbage by accident in the user flash memory, pc will never jump to system memory. Am I right?