Hi,
In my Cortex-M0 project, there are two program images residing at different memory locations: 0x0000_0000 and 0x0010_0000. Each program has its own vector table. M0 will boot from the program at 0x0010_0000 then switch to the other program (0x0000_0000) at the end.
What is the correct way to switch to the porgram at 0x0000_0000? I'm not sure whether the following instructions are correct or not.
LDR R6, =0x1 ; set R6 to 0x0000_0001 due to Thumb mode
LDR R0, [R6]
MOV SP, R0
LDR R1, [R6, #4]
BX R1
Can someone please point me the right implementation? Thanks a lot.
It looks that you are already having two vector tables as well. In that case, you change the VTOR and perform a reset. I am not sure if this is the correct way.
By the way, what is really the need of having 2 images?
jyiu's book Definitive guide to Cortex M3, M4 gives some similar examples (Chapter 7, section 7.5)
Which MCU it is?
gopal.amlekar: It can be useful having two images, where image#1 may update image#2 (for firmware update purposes). If image#2 is not present, image#1 could be either waiting for firmware or execute a 'default' or 'bare minimum' firmware.
Normally image#1 would execute image#2 almost immediately (right after verifying that it actually makes sense and is a valid image).
jacobbeningo wrote an excellent document on the bootloader subject called Bootloader Design for MCU's in Embedded Systems.
You may also be interested in Does anyone know how I can remotely update code to distant arm system?
Thanks jensbauer, So it is similar to bootloader app I guessed. Some MCUs have inbuilt bootloader, isn't it? I think STM32F4 has one.
Also in this particular case, if VTOR is updated in the image #1, then it would later always execute image #2 when power cycled. It won't be able to get back to image #1 unless VTOR is again changed to vector table of image #1.
Changing VTOR isn't permanent; it's just like any other hardware register, and has a default on startup.
-So power-cycling will always execute image#1 in this particular case.
Most microcontrollers have a boot-ROM, yes. This makes it possible to program the devices in other ways than JTAG and SWD, for instance via UART or USB, but this of course depends on the boot-ROM code.
Thanks. I had this misunderstanding of VTOR..
Hi wshen,
I wonder how do you start from 0x0010_0000. If it is possible, I think the reset vector 0x0010_0000 is located at 0x0000_0004. When is the vector table on 0x0000_0000 replaced? Does your system have not flash but SRAM as the vector table?
Best regards,Yasuhiko Koumoto.
Thank you, jensbauer.
There is an issue while compiling this line: "ldr sp,[r0]"
Error: A1875E: Register Rt must be from R0 to R7 in this instruction
The shorter code encounters a different issue at this line: "ldmia r0!, {sp,pc}"
Error: A1874E: Specified register list cannot be loaded or stored in target instruction set
My toolchain is RVDS_4.1_sp1_build713 armcc/armasm/armlink. Do I miss something here?
I think forgot that you're using Cortex-M0 for a while, sorry about that. To fix the ldr sp,[r0], you'll just need to do for instance...
movs r0,#0
ldr r1,=SC
str r0,[r1,#VTOR]
ldr r1,[r0]
mov sp,r1
ldr r1,[r0,#4]
bx r1
... I believe that should fix it. The shorter version, probably won't be fixable; I guess I got too used to Cortex-M3/Cortex-M4.
Yes I'm using Cortex-M0. So there is no VTOR in the System Control block. This leads to the compiling error of these two lines,,,
According to the documentation, on Cortex-M0, the exception vector table is fixed at address 0x00000000.
However, since a vendor can customize the behaviour of virtually anything, I know of one implementation, which allows you to change it, though; perhaps there are more.
Fortunately, Cortex-M0+ has a VTOR.
Which device in particular are you writing code for ?
Cortex-M0, not Cortex-M0+.
I would like to ask you how you can have two set of vector tables.
Hi Yasuhiko,
It appears I have misunderstanding of vector tables on M0. There could be only one vector table existing on M0.
Thanks,wshen
If you can replace the Cortex-M0 by a Cortex-M0+, you would have the VTOR, so you could change vector tables.
Sometimes the vendor of the device makes a pin-compatible device that can replace it.
Now, this question keeps occupying my mind.
If you're only going to copy code to the RAM, then you could also do one of these things:
If you're interested in solution #3, I could send you an example linker-script and some startup-code. I could also write a document about it.