My project is to upgrade (replace) the program running on a STM32F417. It has to be accomplished by plugging in a serial cable to the device and running a Windows app to start the upgrade. The customer performing the upgrade will choose the COM port through a menu of the Windows app. They will then press a button to start the upgrade.
Right now, I have this code in the main loop of the program running on the device:
if( charIn == 'B' )
I can type in a 'B' in the terminal of my C# program and get have the JumpMemory() function run. This will not be the actual trigger, but for testing, I'm just trying to get all the actions necessary to be performed.
So, now that I can trigger a jump out of the main loop of the devices program. I want to reset and enter the bootloader. This is where my knowledge is weak as I have never work with ARM or the bootloader previously.
From posts on this site, I have use the following code snippets:
1) At the top of main.c (function declaration):
JumpMemory(); (and the call to this function listed above)
extern void SystemReset(void);
I'm not sure what this is referring to. There is a SystemReset process in the assembly noted below. Is that what is being called?
2) When JumpMemory() is called a number is written to RAM and then reset is invoked.
*((unsigned long *)0x2001FFF0) = 0xDEADBEEF;
The above and following code is from https://community.st.com/thread/16678?commentID=112864#comment-112864
3) I created a new assembly (.s) file and put in this code. I can see that this Reset Handler will be run instead of the [WEAK] one specified in the startup.s file. It then loads the contents of the address where we place DEADBEEF into a register and then compares it to DEADBEEF we have loaded into another register. They are equal so it jumps to Reboot_Loader instead performing a normal startup.
; Write a known word into SRAM and use it for the 417 to boot into bootloader
LDR R0, =0x2001FFF0 ; Address for RAM signature
LDR R1, =0xDEADBEEF
LDR R2, [R0, #0] ; Read current
STR R0, [R0, #0] ; Invalidate
CMP R2, R1
; Normal startup path
LDR R0, =SystemInit
LDR R0, =__main
; Vector into System 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
ldr r1, =0xE000ED0C ; NVIC Application Interrupt and Controller
ldr r0, =0x05FA0004 ; Magic
str r0, [r1, #0] ; Reset
I was hoping that this would place the operation of the program at the start of the bootloader and would wait for the baud rate byte (0x7F) to be sent. Instead, it skips back into the main loop. I assume that upon reset, it is performing a normal startup.
How do I get the process to stop at the beginning of the bootloader?
Do I have the system reset set up properly?
Should the assembly be in a separate file, as I have it, or somewhere else?
Is the NVIC reset the proper one to use?
Thank you for helping!