cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Internal Bootloader

bogdan1
Associate
Posted on April 08, 2009 at 20:49

STM32 Internal Bootloader

#bootloader-started-by-software
10 REPLIES 10
bogdan1
Associate
Posted on May 17, 2011 at 13:09

STM32F103xx has an internal ROM bootloader residing at address 0x1FFFF000 of about 2K. It runs if the user boots in the System mode and STM32 is reset. I found that the bootloader is accessible at the same address (0x1FFFF000) from the regular user FLASH mode.

Are there any restrictions in calling the bootloader from a FLASH application and then would there be a way to jump to the application after the download? This last feature is supported by the bootloader (command 0x21).

--

Thanks, Bogdan

damh
Associate II
Posted on May 17, 2011 at 13:09

You can start the internal bootloader by software as following:

1) your mcu must be in system mode

2) set MSP/R13 to value from 0x1FFFF000 (normally 0x20000200)

3) Load address from 0x1FFFF004 (normally 0x1FFFF021)

4) Jump to this address

The host pc has to do the rest!

Posted on May 17, 2011 at 13:09

You can call code in the Boot ROM as you can any other. If you want to run the whole thing, don't expect it to return to your application, or have the clocks/interrupt set in the way you had them.

Generally I would recommend reseting into the Boot ROM so it starts without random clocks and interrupts enabled from your application.

In application.c

                // 1FFFF000 -> 20000200 -> SP

                // 1FFFF004 -> 1FFFF021 -> PC

                printf(''Entering Boot Loader..\r\n'');

                *((unsigned long *)0x2000FFF0) = 0xDEADBEEF; // 64KB STM32F103

                NVIC_GenerateSystemReset();

In startup.s

; Reset Handler

Reset_Handler   PROC

                EXPORT  Reset_Handler             [WEAK]

                IMPORT  __main

                LDR        R0, =0x2000FFF0

                LDR        R1, =0xDEADBEEF

                LDR        R2, [R0, #0]

                STR        R0, [R0, #0] ; Invalidate

                CMP        R2, R1

                BEQ        Reboot_Loader

                LDR     R0, =__main

                BX      R0

                ENDP

Reboot_Loader    PROC

                EXPORT    Reboot_Loader

                LDR        R0, =0x1FFFF000

                LDR        SP,[R0, #0]

                LDR        R0,[R0, #4]

                BX        R0

                ENDP

-Clive
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
junmar77
Associate II
Posted on May 17, 2011 at 13:09

clive1,

do you know how we can do it in IAR EWARM?

Posted on May 17, 2011 at 13:09

What version? Not too familiar with IAR EWARM, you'll have to look to see how the startup vector works, and how you might change the startup code. If you want to buy me a copy, I'll create a worked example.

You could look for

startup_stm32f10x_ld.s

__iar_program_start

Or

stm32f10x_vector.c

__program_start Or

startup.s

With GCC I might look in stm32f10x-vector.c, and add some code in Reset_Handler()

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
toro
Associate
Posted on January 19, 2014 at 15:14

Hi clive1,

How do this on stm32f051.

I tried this without succes,

the problem error on startup.s:

ldr        sp,[r0, #0]

''cannot honor width suffix -- `ldr sp,[r0,#0]' ''

if changed to r13:

ldr        r13,[r0, #0]

''cannot honor width suffix -- `ldr sp,[r0,#0]' ''

Posted on January 19, 2014 at 16:35

Yes, well the Cortex-M0 only supports a subset of the instruction set.

Reboot_Loader PROC
EXPORT Reboot_Loader
LDR R0, =0x1FFFEC00 ; System Memory STM32F0
LDR R1,[R0, #0]
MOV SP,R1
LDR R0,[R0, #4]
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..
toro
Associate
Posted on January 20, 2014 at 04:21

Thanks clive1, it's working now,,,

martin239955_st
Associate
Posted on April 13, 2015 at 17:58

Hi Clive1

Sorry to bring up such an old thread but I am implementing this right now and i wonder if you belive that it is necessery to clear the deadbeaf from the controlling device? We are using this to do firmware over the air updates and the plan right now is to have the controlling software look at the specific address and overwrite it with 0 if it still is deadbeaf. Does it seem like a good approach or should a GO command to the reset vector

be all that is needed

Best regrds

Martin