I am currently trying to develop my own bootloader for an Atmel SAM R21. My idea is to run the bootloader firstly, so it will decide if an update is needed to be performed or just jumping to the application. The main problem is that the Interrupt Vector Table is located at the 0x0000_0000 address, so it needs to be relocated just before the application code, so if the bootloader has a 8KB space set in the linker file and using the BOOTPROT fuse in that way (setting this fuse it is supposed that there will be some protection to the amount of memory selected through the fuse), the vector table should start at the 0x0000_2000 address. In order to relocate the vector table I pretend to use the VTOR register, which is an offset applied to the original table address (0x0000_0000). The assembly code is the following:
asm(" LDR R0,=0xE000ED08 "); //VTOR ADDRESS
asm("LDR R1,=0x00002000"); //OFFSET
asm(" STR R1, [R0]");
asm(" LDR R0,[R1] ");
asm(" MOV SP, R0");
asm(" LDR R0,[R1, #4]");
asm(" BX R0");
LDR instruction gives me the following error: Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error"
What am I doing wrong? Maybe I am trying to use ARM instruction instead of a Thumb one?
I will very appreciate any advise.
I am also doubting if once I get the Interrup Vector Table relocated, should I count with the Initial MSP value also? I want to mean, if the Interrupt Vector table starts at address 0x0000_2000 after being relocated, I should count 4(bytes) * Interrupt in order to know which should be the initial application address, shouldn't I? If someone knows something about this it would be nice. I know I am close (or I think so), but I need to clarify those points.
Edited 27/06/16 at 13:04. This instruction works LDR R0,[R1] So I guess it is something related to receive the 32 bits address into the register, but I don't understand why it is complaining about this.
SOLUTION:
As an answer to my question, someone posted that not all assembly directives can be used inlined, so I needed to create an assembler file, my_file.s In this file should be created a function to be called from outside, something like this:
#define _PORT_ASM_ARM_SRC
#define __ASSEMBLY__
;/****************************************************************************
;** **
;** ASSEMBLY FUNCTIONS **
;** **
;****************************************************************************/
NAME start_app
RSEG CODE:CODE(2)
THUMB
PUBLIC jump_to_app
;/***************************************************************************/
;/***************************************************************************/
;/* jump_to_app()
; * Jump to application function.
; */
jump_to_app:
LDR R0,=0xE000ED08 ; Set R0 to VTOR address
LDR R1,=0x00010000 ; User’s flash memory based address
STR R1, [R0] ; Define beginning of user’s flash memory as vector table
LDR R0,[R1] ; Load initial MSP value
MOV SP, R0 ; Set SP value (assume MSP is selected)
LDR R0,[R1, #4] ; Load reset vector
BX R0 ; Branch to reset handler in user’s flash
END
After doing this, the function prototipe should be included into a .h file of your project as a normal function, using something like this:
void jump_to_app(void);
Best regards,
Iván.
R1,=0x00002000, which happens to have the label "LDR" ;) - Notlikethat