2017-07-19 08:58 AM
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 startupBEQ 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 startupBEQ 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.Solved! Go to Solution.
2019-12-10 01:58 PM
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