- movs r0, #0x00 /* Locate the top of stack. */\r
- ldr r0, [r0]\r
- msr msp, r0 /* Set the msp back to the start of the stack. */\r
- cpsie i /* Globally enable interrupts. */\r
- svc 0 /* System call to start first task. */\r
- nop\r
+ /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector\r
+ table offset register that can be used to locate the initial stack value.\r
+ Not all M0 parts have the application vector table at address 0. */\r
+\r
+ ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */\r
+ ldr r1, [r3]\r
+ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */\r
+ adds r0, #32 /* Discard everything up to r0. */\r
+ msr psp, r0 /* This is now the new top of stack to use in the task. */\r
+ movs r0, #2 /* Switch to the psp stack. */\r
+ msr CONTROL, r0\r
+ isb\r
+ pop {r0-r5} /* Pop the registers that are saved automatically. */\r
+ mov lr, r5 /* lr is now in r5. */\r
+ cpsie i /* The first task has its context and interrupts can be enabled. */\r
+ pop {pc} /* Finally, pop the PC to jump to the user defined task code. */\r
+\r
+ ALIGN\r