cancel
Showing results for 
Search instead for 
Did you mean: 

Calling stm32429I-Eval Bootloader

chuck2
Associate
Posted on May 02, 2014 at 01:26

Hello, we are wanting to call the built-in bootloader from our application without manipulating the BOOT0/BOOT1 pins. I am trying to use the EVAL board to validate our method. The Users Manual for the Eval board does state:  ''The RS-232 boot loader mechanism is not supported on the STM32429I-EVAL''. There is no explanation of this statement. However, if I move the Boot0 switch on the eval board to 1 and power cycle, I am able to at least connect to the bootloader over RS-232 using the ST demo flash loader program. If I can get that far by calling the bootloader on the Eval board with the BOOT pins both at 0, I will call it a success until our hardware is ready.

I have tried both calling the bootloader from C code, using the method posted on Youtube, and also calling it from my startup assemble code, using the method Clive has suggested in the forum, as follows (I am using IAR):

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Default interrupt handlers.

;;

THUMB

PUBWEAK Reset_Handler

SECTION .text:CODE:REORDER:NOROOT(2)

Reset_Handler

LDR R0,=0x1FFF0000

LDR R1,[R0,#0]

MOV SP,R1

LDR R0,[R0,#4]

BX R0            ;debugger shows 0x1FFF4ABF in R0 at this point

Unfortunately, both methods display the same behavior - I cannot connect to the bootloader using the demo program. If I use the debugger, I can hit a breakpoint at the start of the bootloader (at 0x1FFF4ABE) , and can trace through it until I get bored, but as soon as I hit run, I hit a breakpoint back at the BX R0 line above, as if a reset is occurring, or the bootloader is jumping back to the start of the application. This made me suspect the dual boot mode of the 429, but I used ST-Link to verify the BFB2 bit in the options byte is cleared, so no dual boot should be taking place.

Any ideas?
32 REPLIES 32
Posted on May 02, 2014 at 01:55

Try this

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 ; 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
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..
chuck2
Associate
Posted on May 02, 2014 at 18:03

Wow - you are the man, Clive. That worked like a champ. Thank you!

Wood.Andy
Associate III
Posted on December 01, 2014 at 11:58

Hi Clive

You got me out of the cr@p again!

Thanks

Andy.

hbarta2
Associate III
Posted on July 10, 2015 at 21:32

Any pointers on how to use this when building with the IAR tools would be most welcome!

Thanks.

I had a longer and more descriptive post, but the forum software didn't post it. >:(

hbarta2
Associate III
Posted on July 10, 2015 at 22:11

I think I figured this out by adding the following to startup_stm32f429xx.s after the Reset_Handler

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 ; 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

and then prototyping this in C as

void Reboot_Loader(void);

I can step into it and at the end step into the code it branches to at 0x1ffff5138 which looks reasonable to my untrained eye.

0x1fff5132: 0x2000 MOVS R0, #0
0x1fff5134: 0x0af9 LSRS R1, R7, #11
0x1fff5136: 0x0000 MOVS R0, R0
0x1fff5138: 0xf000 0xf809 BL 0x1fff514e <<<<<<<<<<<<<<<<<<<<<<<<<< entry to bootloader?
0x1fff513c: 0x2800 CMP R0, #0
0x1fff513e: 0xd001 BEQ.N 0x1fff5144
0x1fff5140: 0xf7ff 0xffd0 BL 0x1fff50e4
0x1fff5144: 0x2000 MOVS R0, #0
0x1fff5146: 0xf7fb 0xf81f BL 0x1fff0188
0x1fff514a: 0xf000 0xf802 BL 0x1fff5152
0x1fff514e: 0x2001 MOVS R0, #1
0x1fff5150: 0x4770 BX LR
0x1fff5152: 0xf000 0xb801 B.W 0x1fff5158
0x1fff5156: 0x0000 MOVS R0, R0
0x1fff5158: 0x4607 MOV R7, R0
0x1fff515a: 0x4638 MOV R0, R7
0x1fff515c: 0xf7ff 0xff6a BL 0x1fff5034
0x1fff5160: 0xe7fb B.N 0x1fff515a
0x1fff5162: 0x46c0 MOV R8, R8
0x1fff5164: 0x46c0 MOV R8, R8
0x1fff5166: 0x46c0 MOV R8, R8
0x1fff5168: 0x46c0 MOV R8, R8
0x1fff516a: 0xf7ff 0xffe5 BL 0x1fff5138
0x1fff516e: 0xf7fd 0xb97f B.W 0x1fff2470
0x1fff5172: 0xf7ff 0xbf69 B.W 0x1fff5048
0x1fff5176: 0x1110 ASRS R0, R2, #4

Executing from that point results in a reset in several seconds. Is this 'not working' or do I need to de-init the H/W to simulate a reset before calling that routine? Thanks! Edit: (Just found the edit button. 😉 ) Calling this as the first thing on main() does bring up the bootloader so it must be something to do with the subsequent H/W init. I suppose the best way to handle this is to set some flag (RTC backup register?) and reset then test and call immediately on entry to main.
Posted on July 10, 2015 at 22:15

; Quick IAR blind port
; Placed in startup_stm32f4xx.s after Reset_Handler,
; ideally called from there as magic number reset.
; In C defined as extern void Reboot_Loader(void);
; called as Reboot_Loader();
PUBLIC Reboot_Loader
SECTION .text:CODE:NOROOT:REORDER(1)
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 ; MAP ROM AT ZERO
STR R1, [R0, #0]
; LDR R0, =0x1FFF0000 ; ROM BASE
LDR R0, =0x00000000 ; OR GENERICALLY MAPPED AT ZERO
LDR SP,[R0, #0] ; SP @ +0
LDR R0,[R0, #4] ; PC @ +4
BX R0
; sourcer32@gmail.com

To better understand the context review this thread

/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

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

Crossed on the wire there, preparing IAR'ish assembler, not an EWARM guy.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
hbarta2
Associate III
Posted on July 11, 2015 at 00:14

Many thanks for your help, Clive. 

And I'm not an assembler guy. 😉 But I did manage to get this to work. Unfortunately it only works if called before SystemClock_Config() in main (HAL/Cube libraries) so I'm trying to figure out how to set a flag somewhere that the app can test/clear on the nest reset. But that's a topic for another thread. ([DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Set%20a%20flag%20to%20test%20after%20reset&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx&currentviews=0]another thread)

Thanks!

Posted on July 11, 2015 at 01:33

Well the premise of the 5 year old thread I cited is that you write a magic valid in RAM, reset/restart the STM32 and during the Reset Handler it kicks directly into the ROM in close to reset conditions, and you avoid all the nonsense about clocks, plls and interrupts.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..