cancel
Showing results for 
Search instead for 
Did you mean: 

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

Gordon Madden
Associate III
Posted on July 19, 2017 at 17:58

I have successfully built a firmware upgrade app using C# and the bootloader in the STM32F4 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!

#armlink #linker #execution-region #jump-memory #robust #firmware-upgrade #scatter-file

Note: this post was migrated and contained many threaded conversations, some content may be missing.
10 REPLIES 10
				IMPORT	|Load$$LR$$LR_IROM1$$Length|
				DCD	|Load$$LR$$LR_IROM1$$Length|

The load region can work better if Keil has compressed the initialization data

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