This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex-M0: How to switch from one program to another

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.

Parents
  • Note: r6 should be 0, not 1.

    It's only necessary to set bit 0 in PC, that is if you're changing PC directly.

    So you should load the SP from address 0x00000000 and PC from address 0x00000004.

    Bit 0 is already set for all handlers in the vector table, so you do not need to change anything.

    ARM recommends using BX to load PC:

                movs        r0,#0

                ldr         r1,=SC

                str         r0,[r1,#VTOR]

                ldr         r1,[r0]

                mov         sp,r1

                ldr         r1,[r0,#4]

                bx          r1

    ... but if you need the code to be shorter, I believe the following will work ...

                movs        r0,#0

                ldr         r1,=SC

                str         r0,[r1,#VTOR]

                ldmia       r0!,{r0,r1}

                mov         sp,r0

                bx          r1

    Edit: I've corrected this answer, so it would work for Cortex-M0+. As mentioned below, the Cortex-M0 (without plus), does not have the hardware register VTOR.

Reply
  • Note: r6 should be 0, not 1.

    It's only necessary to set bit 0 in PC, that is if you're changing PC directly.

    So you should load the SP from address 0x00000000 and PC from address 0x00000004.

    Bit 0 is already set for all handlers in the vector table, so you do not need to change anything.

    ARM recommends using BX to load PC:

                movs        r0,#0

                ldr         r1,=SC

                str         r0,[r1,#VTOR]

                ldr         r1,[r0]

                mov         sp,r1

                ldr         r1,[r0,#4]

                bx          r1

    ... but if you need the code to be shorter, I believe the following will work ...

                movs        r0,#0

                ldr         r1,=SC

                str         r0,[r1,#VTOR]

                ldmia       r0!,{r0,r1}

                mov         sp,r0

                bx          r1

    Edit: I've corrected this answer, so it would work for Cortex-M0+. As mentioned below, the Cortex-M0 (without plus), does not have the hardware register VTOR.

Children