diff --git a/libraries/Scheduler/library.properties b/libraries/Scheduler/library.properties index c7d34533b..c9ee1d5c4 100644 --- a/libraries/Scheduler/library.properties +++ b/libraries/Scheduler/library.properties @@ -1,9 +1,9 @@ name=Scheduler -version=0.4.3 +version=0.4.4 author=Arduino maintainer=Arduino -sentence=Allows multiple tasks to run at the same time, without interrupting each other. For Arduino DUE only. -paragraph=The Scheduler library enables the Arduino Due to run multiple functions at the same time. This allows tasks to happen without interrupting each other.
This is a cooperative scheduler in that the CPU switches from one task to another. The library includes methods for passing control between tasks. +sentence=Allows multiple tasks to run at the same time, without interrupting each other. For Arduino sam and samd architectures only (Due, Zero...). +paragraph=The Scheduler library enables the Arduino to run multiple functions at the same time. This allows tasks to happen without interrupting each other.
This is a cooperative scheduler in that the CPU switches from one task to another. The library includes methods for passing control between tasks. category=Other url=http://www.arduino.cc/en/Reference/Scheduler -architectures=sam +architectures=sam,samd diff --git a/libraries/Scheduler/src/Scheduler.cpp b/libraries/Scheduler/src/Scheduler.cpp index 2be2d8206..6d7d676c2 100644 --- a/libraries/Scheduler/src/Scheduler.cpp +++ b/libraries/Scheduler/src/Scheduler.cpp @@ -53,10 +53,30 @@ static void __attribute__((naked)) __attribute__((noinline)) coopTaskStart(void) asm ( "mov r0, r5;" "blx r4;" - "mov r0, #1;" + /* schedule. */ + "mov r0, #1;" /* returned from task func: task done */ "bl coopSchedule;" + /* r0 holds address of next task context */ +#if defined(ARDUINO_ARCH_SAMD) + /* for cortex m0, ldm and stm are restricted to low registers */ + /* load high registers */ + "add r0, #16;" /* they are 4 words higher in memory */ + "ldmia r0, {r1-r6};" /* load them in low registers first... */ + "mov r8, r1;" /* ...and move them into high registers... */ + "mov r9, r2;" + "mov r10, r3;" + "mov r11, r4;" + "mov r12, r5;" + "mov lr, r6;" + /* load low registers */ + "sub r0, r0, #40;" /* back to begin of context */ + "ldmia r0, {r4-r7};" +#else "ldmia r0, {r4-r12, lr};" +#endif + /* restore task stack */ "mov sp, r12;" + /* resume task */ "bx lr;" ); } @@ -64,11 +84,44 @@ static void __attribute__((naked)) __attribute__((noinline)) coopTaskStart(void) static void __attribute__((naked)) __attribute__((noinline)) coopDoYield(CoopTask* curTask) { asm ( "mov r12, sp;" +#if defined(ARDUINO_ARCH_SAMD) + /* store low registers */ + "stmia r0, {r4-r7};" + /* store high registers */ + "mov r1, r8;" /* move them to low registers first. */ + "mov r2, r9;" + "mov r3, r10;" + "mov r4, r11;" + "mov r5, r12;" + "mov r6, lr;" + "stmia r0, {r1-r6};" +#else "stmia r0, {r4-r12, lr};" - "mov r0, #0;" +#endif + /* schedule. */ + "mov r0, #0;" /* previous task did not complete */ "bl coopSchedule;" + /* r0 holds address of next task context */ +#if defined(ARDUINO_ARCH_SAMD) + /* for cortex m0, ldm and stm are restricted to low registers */ + /* load high registers */ + "add r0, #16;" /* they are 4 words higher in memory */ + "ldmia r0, {r1-r6};" /* load them in low registers first... */ + "mov r8, r1;" /* ...and move them into high registers... */ + "mov r9, r2;" + "mov r10, r3;" + "mov r11, r4;" + "mov r12, r5;" + "mov lr, r6;" + /* load low registers */ + "sub r0, r0, #40;" /* back to begin of context */ + "ldmia r0, {r4-r7};" +#else "ldmia r0, {r4-r12, lr};" +#endif + /* restore task stack */ "mov sp, r12;" + /* resume task */ "bx lr;" ); }