Skip to main content
Kevin Lehzen
Associate II
January 26, 2018
Solved

Jump to internal Bootloader with STM32F7

  • January 26, 2018
  • 9 replies
  • 4803 views
Posted on January 26, 2018 at 16:55

Hi there,

we are currently developing the firmware for our custom board with an STM32F746 MCU in LQFP-100 package. Our current version is working well and now we want to be able to download updates via USB DFU. I read many posts and the related documents from ST, so there might be some ways to realize this. Unfortunately, in either way we get stuck on  choosing the right addresses or verifying code with DfuSe. My favorite way is the following in which we jump to the internal bootloader:

&sharpdefine SYS_MEM_ADD                              0x1FF00000

 

//Disables the RCC (reset setting)

HAL_RCC_DeInit();

SysTick->CTRL = 0;

SysTick->LOAD = 0;

SysTick->VAL = 0;

// disables every IRQ

__disable_irq();

// remap system memory to 0x0000 0000

SYSCFG->MEMRMP = 0x01;

JumpToApplication = (void (*)(void)) (*((uint32_t *)(SYS_MEM_ADD + 4)));

__set_MSP(*(__IO uint32_t*) SYS_MEM_ADD);

JumpToApplication();

while(1);

 

 

The problem is that this way is just working in debug mode (toolchain SW4STM32 with Segger J-link). So my breakpoint is at JumpToApplication() and when I go one step further the device appears in DfuSe with the correct memory mapping (DFU update possible). In normal run mode the application is running and while switching to DFU/Bootloader mode the MCU just resets. I tried some different addresses but nothing would work. Maybe there is another way or something wrong in the IDE settings?

I appreciate every help. Thanks in advance!

Regards,

Kevin Lehzen

#stm32f7
This topic has been closed for replies.
Best answer by Clive1 (HNL)
Posted on January 27, 2018 at 02:51

This brought up 'STM32 BOOTLOADER' on the STM32F746G-DISCO for me

//***************************************************************************
void BootDFU(void)
{
 printf('Entering Boot Loader..

');
 SCB_DisableDCache();
 *((unsigned long *)0x2004FFF0) = 0xDEADBEEF; // 320KB STM32F7xx
 __DSB();
 NVIC_SystemReset(); 
}
//***************************************************************************

; Reset handler
Reset_Handler PROC
 EXPORT Reset_Handler [WEAK]
 IMPORT SystemInit
 IMPORT __main
 LDR R0, =0x2004FFF0 ; Address for RAM signature
 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 ; STM32F7xx
 LDR R0, =0x1FF00000 ; ROM BASE
 LDR SP, [R0, #0] ; SP @ +0
 LDR R0, [R0, #4] ; PC @ +4
 BX R0
 ENDP ; sourcer32@gmail.com
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

9 replies

Clive1 (HNL)
Explorer
January 26, 2018
Posted on January 26, 2018 at 18:50

A blanket disabling of IRQs is unhelpful, where would that get enabled again? Does this reflect the state at reset? Turn off your interrupt sources at the peripheral.

Don't call the loader from an interrupt context.

Would have to see if the system loader is testing for the dual bank boot.

Clive1 (HNL)
Clive1 (HNL)Best answer
Explorer
January 27, 2018
Posted on January 27, 2018 at 02:51

This brought up 'STM32 BOOTLOADER' on the STM32F746G-DISCO for me

//***************************************************************************
void BootDFU(void)
{
 printf('Entering Boot Loader..

');
 SCB_DisableDCache();
 *((unsigned long *)0x2004FFF0) = 0xDEADBEEF; // 320KB STM32F7xx
 __DSB();
 NVIC_SystemReset(); 
}
//***************************************************************************

; Reset handler
Reset_Handler PROC
 EXPORT Reset_Handler [WEAK]
 IMPORT SystemInit
 IMPORT __main
 LDR R0, =0x2004FFF0 ; Address for RAM signature
 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 ; STM32F7xx
 LDR R0, =0x1FF00000 ; ROM BASE
 LDR SP, [R0, #0] ; SP @ +0
 LDR R0, [R0, #4] ; PC @ +4
 BX R0
 ENDP ; sourcer32@gmail.com
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Kevin Lehzen
Associate II
January 29, 2018
Posted on January 29, 2018 at 20:30

Thanks Clive,

I am sorry but I am a bit confused where to put the assembler code. Looks like its something for the startup...s?

Kind regards,

Kevin

Kevin Lehzen
Associate II
February 1, 2018
Posted on February 01, 2018 at 10:02

Thanks for your help, Clive. Now it works!

Cheers

Mike Hooper
Associate III
April 22, 2018
Posted on April 22, 2018 at 18:57

 ,

 ,

Kevin, Clyde,

In the spirit of paying it forward, here is a working version using Atollic format for the F765.

 ,

Reset_Handler:

 ,

ldr r0, =0x2004FFF0

 ,

ldr r1, =0xDEADBEEF

 ,

ldr r2, [r0, ♯ 0]

 ,

str r0, [r0, ♯ 0]

 ,

cmp r2, r1

 ,

beq Reboot_Loader

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

 ,

/* Copy the data segment initializers from flash to SRAM */

 ,

movs r1, ♯ 0

 ,

b LoopCopyDataInit

ldr r0, =SystemInit

 ,

blx r0

 ,

bl main

Reboot_Loader:

 ,

ldr r0, =0x1FF00000

 ,

ldr sp, [r0, ♯ 0]

 ,

ldr r0, [r0, ♯ 4]

 ,

bx r0

LoopForever:

 ,

b LoopForever

CopyDataInit:

 ,

ldr r3, =_sidata

 ,

ldr r3, [r3, r1]

 ,

str r3, [r0, r1]

 ,

adds r1, r1, ♯ 4

 ,

 ,

LoopCopyDataInit:

 ,

ldr r0, =_sdata

 ,

ldr r3, =_edata

 ,

adds r2, r0, r1

 ,

cmp r2, r3

 ,

bcc CopyDataInit

 ,

ldr r2, =_sbss

 ,

b LoopFillZerobss

 ,

/* Zero fill the bss segment. */

 ,

FillZerobss:

 ,

movs r3, ♯ 0

 ,

str r3, [r2], ♯ 4

 ,

 ,

LoopFillZerobss:

 ,

ldr r3, = _ebss

 ,

cmp r2, r3

 ,

bcc FillZerobss

/* Call the clock system initialization function.*/

 ,

bl SystemInit

 ,

/* Call static constructors */

 ,

bl __libc_init_array

 ,

/* Call the application's entry point.*/

 ,

bl main

 ,

bx lr

 ,

.size Reset_Handler, .-Reset_Handler

Thanks Clive!

Clive1 (HNL)
Explorer
September 11, 2018

Well the forum transition seems to have made a dog's breakfast of the original post, and is apparently too large and malformed to bring up the editor window.

This brought up 'STM32 BOOTLOADER' on the STM32F746G-DISCO for me

//***************************************************************************
 
void BootDFU(void)
{
 printf("Entering Boot Loader..\r\n");
 
 SCB_DisableDCache();
 
 *((unsigned long *)0x2004FFF0) = 0xDEADBEEF; // 320KB STM32F7xx
 
 __DSB();
 
 NVIC_SystemReset();
}
 
//***************************************************************************
 
; Reset handler
Reset_Handler PROC
 EXPORT Reset_Handler [WEAK]
 IMPORT SystemInit
 IMPORT __main
 
 LDR R0, =0x2004FFF0 ; Address for RAM signature
 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 ; STM32F7xx
 
 LDR R1, =0xE000ED00 ; SCB
 LDR R0, =0x1FF00000 ; ROM BASE
 STR R0, [R1, #8] ; VTOR
 LDR SP, [R0, #0] ; SP @ +0
 LDR R0, [R0, #4] ; PC @ +4
 BX R0
 ENDP ; sourcer32@gmail.com
 
//***************************************************************************

Clive1 (HNL)
Explorer
September 11, 2018

0690X000006C0mqQAC.jpg

Duy Tran
Associate III
September 26, 2018

@Community member​ hi Clive,

Can you help me with the JumpToApplication() in STM32F767 in IAR? After programming the flash inside my program, I only call this function (I don't know where to config the regs etc.)

#define FIRMWARE_ADDR 0x080C0000

JumpToApplication = (void (*)(void)) (*((uint32_t *)(FIRMWARE_ADDR+ 4)));

__set_MSP(*(__IO uint32_t*) FIRMWARE_ADDR);

JumpToApplication();

Thank you very much,

Duy

Tesla DeLorean
Guru
September 26, 2018

Why couldn't this have been a new thread, it's off-topic here?

Ok, that is at the base of FLASH, wouldn't the processor automatically be calling that?

Normally you put the loader at 0x08000000 and the app deeper in, like 0x08008000

The registers are described in the Reference Manual.

What's not working with the code here? Have you stepped into it? Are you building the App for that address base, or somewhere else?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Duy Tran
Associate III
September 26, 2018

Oh sorry, my bad, the address I jumped to was 0x080C0000

I disabled the interrupt but something keep the code stuck in the RCC init function.

Tesla DeLorean
Guru
September 26, 2018

Interrupts must be enabled on the app side if you do that. Also make sure that SCB->VTOR in SystemInit() within the App reflects the new base address for the image.

Have a fault handler that outputs useful data for diagnostics.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Duy Tran
Associate III
September 26, 2018

It runs now, thank you Clive