2014-05-01 04:26 PM
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_HandlerLDR 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?2015-08-05 12:01 PM
Let me try again....
Thanks! Syntaxfor IARReboot_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
Tried to reply earlier and couldn't post. This is my second try today.
2015-08-19 06:49 PM
Hank, Clive,
First of all, thanks for this post, its been helpful. Im trying to do exactly what hank is doing but i always get a ''hardfault''. Im using keil V5 and STM32F427 This is my code in the startup.sReset_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, =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 in C main():
// executed by the program.
HAL_RCC_DeInit();
SysTick->CTRL = 0x00;
SysTick->LOAD = 0x00;
SysTick->VAL = 0;
//__set_PRIMASK(1);
// JumpAddress = *(__IO uint32_t*) (0x1fff0004);
// SysMemBootJump =(void *)JumpAddress;
// __set_MSP(*(volatile unsigned int *)0x1FFF0000);
// SysMemBootJump();
Reboot_Loader();
2015-08-19 11:43 PM
The mechanism is not to call the routine directly, but via a tag in RAM and a reset. Pick a chip appropriate address in the C and Assembler routines.
printf(''Entering Boot Loader..\r\n'');
*((unsigned long *)0x2000FFF0) = 0xDEADBEEF; // 64KB STM32F103
NVIC_SystemReset();
2015-08-20 12:33 AM
Thanks Clive! I made it work using an old post from you
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
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 ; 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
BX R0
ENDP ;
Its there and advantage of using the mark in the RAM? Whats the purpose of doing this?
Now, im with the issue of disabling every module in the MCU, to jump to the bootloader. My current application uses the following modules:
DCMI
DMA
FMC
USB
USART
I2C
SPI
Do i need disable all modules that im using?
Thanks a lot!!!
2015-08-20 12:42 AM
Clive! Never mind, im being redundant, i understood what you said to me in the previous post!
Thanks for the help!2015-10-09 03:07 PM
Hi,
I've searched and analysed a lot of Clive1 posts (you're great!!). I did implement the 0xDEADBEEF in RAM and the .s. In the posts you have in this thread, I'm trying to understand this:LDR R0, =0x40013800 ; SYSCFG_MEMRMP
LDR R1, =0x00000001 ; MAP ROM AT ZERO
I don't have that in my code and maybe that's the reason I'm experiencing this behavior:
- User App starts
- Write 0xDEADBEEF in RAM
- Soft Reset
- Assembly reset code compares memory, 0xDEADBEEF is found
- Reboot_Loader is called
- Jumping to embedded bootloader
- Some code executes
- User App is recalled again
- and so on.
From what I understand, I'm not staying in the embedded bootloader, it's jumping back in my application. Then, since it's an infinite loop, the hard fault handler is called.
Am I missing something?
Thanks for your time,
DT
2015-10-09 03:55 PM
Ok, confirm what processor you're using, and the precise code sequences you have doing the reset, and in the reset handler.
The two lines load immediate constants into the processor registers, the line afterward copies the ONE constant into the SYSCFG->MAPRMP register, whose address I hard-coded. The purpose here is to do the equivalent memory mapping (shadowing) caused by the BOOTx pins. ie the ROM also appears at 0x00000000 in the memory map, instead of your FLASH code.2015-10-13 05:38 AM
Hi,
this is the code as it is currently. I changed it a little from the original post I saw from you because I was trying things to make it work. MCU is:STM32F427ZIT6, using IAR. My setup function:BOOL BSPResetBoard(BOOL bBootload)
{
if (bBootload)
{
*((unsigned long *)0x2001BFF0) = 0xDEADBEEF;
}
hal_BSPSoftwareReset();
return TRUE;
}
Assembly code in startup_stm32f427xx.s:
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
LDR R0, =0x2001BFF0
LDR R1, =0xDEADBEEF
LDR R2, [R0]
STR R0, [R0]
CMP R2, R1
BEQ Reboot_Loader
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0
PUBWEAK Reboot_Loader
SECTION .text:CODE:REORDER:NOROOT(2)
Reboot_Loader
LDR R0, =0x00000000
LDR SP, [R0, #0]
LDR R0, =0x1FFF0004
BX R0
(sorry for alignment, didn't paste well...)
Thanks !!
DT
2015-10-13 09:29 AM
Ok, the thing you're not grasping here is that 0x1FFF0004 is not executable code you can jump too, but a pointer to some code. In fact if you jump to it, you'll get a Hard Fault.
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
LDR R0, =0x2001BFF0
LDR R1, =0xDEADBEEF
LDR R2, [R0]
STR R0, [R0]
CMP R2, R1
BEQ Reboot_Loader
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0
PUBWEAK Reboot_Loader
SECTION .text:CODE:REORDER:NOROOT(2)
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
2015-10-13 09:58 AM
alright thanks. I'll try that tomorrow (can't try it today).
One question I have. How does the ST bootloader behave after that? Will it stay in Bootloader as long as there is no UART connection to it? Or will it try to jump again in User Code after a specific time (since the User App is still good)?I presume that when loading new data via the Bootloader, the RAM will be reset (so will the DEADBEEF flag)?Sorry for those questions. I usually play with a user bootloader, so not sure what to expect :)Thanks!