AnsweredAssumed Answered

How to jump to another execution region defined by a scatter file?

Question asked by Gordon Madden on Jul 19, 2017
Latest reply on Aug 3, 2017 by Clive One

I have successfully built a firmware upgrade app using C# and the bootloader in the STM32F417. To make it more robust, I am adding a scatter file based on CliveOne's recommendation:

I'd generally recommend having a boot loader at the base of memory (0x08000000, 16KB for the STM32 F2/F4), and then never erase that. Then place the app code above that, and have the boot loader validate the app code before jumping to it. This protects you if the power fails during an update, and makes things far more robust.

 

The 417 will startup at 0x08000000, calculate a checksum on the installed firmware, and then if it matches will continue on to a normal startup (unless an upgrade has been indicated, and then it will do that).

My question is: How to make the jump from the first executable region (0x08000000-0x08003FFF) where the checksum function is, to the normally-running app starting at 0x08004000?

 

Here is my code for getting into the bootloader:

; NORMAL UPGRADE STARTUP
                LDR     R0, =0x2001FFF0      ; Load address of WORD placed in SRAM from MAIN.C
                LDR     R1, =0xDEADBEEF      ; Load same value stored above to a register
                LDR     R2, [R0, #0]         ; Read the current value stored at 0x2001FFF0
                STR     R0, [R0, #0]         ; Erase the value store in SRAM (next restart will
                                               be normal) [stores address as value for R0]

                CMP     R2, R1               ; If values match (DEADBEEF), jump to bootloader,
                                               otherwise continue startup

                BEQ     Reboot_Loader        ; Jump to Reboot Loader below

 

; INTERRUPTED UPGRADE
                LDR     R0, =0x2001FFA0      ; Load address of WORD placed in SRAM from MAIN.C,
                                             ; indicates that the bootloader was previously active
                                             ; This word will be overwritten after the upgrade is                                                completed.
                LDR     R1, =0xCAFEBABE      ; Load same value stored at above address to a                                                register
                LDR     R2, [R0, #0]         ; Read what is stored at 0x2001FFA0
                CMP     R2, R1               ; If values match (CAFEBABE), jump to bootloader,
                                               otherwise continue startup

                BEQ     Reboot_Loader        ; Jump to Reboot Loader below
 
; Normal startup path
                LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
                BX      R0
                ENDP
;... 
            ; Vector into System Loader
            ; Sets up board for bootloader mode
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
 
SystemReset     PROC
                EXPORT  SystemReset
                ldr     r1, =0xE000ED0C ; NVIC Application Interrupt and Controller
                ldr     r0, =0x05FA0004 ; Magic
                str     r0, [r1, #0]    ; Reset
                b       .
                ENDP
 

Do I have to do another system reset or is there a way to jump into the firmware on completion of the checksum. When doing an upgrade, I use the GO command to leave the bootloader and start executing code.

 

Thank you!

Outcomes