For Cortex-M3,Cortex-M0, Multitask scheduler library. Arduino due compatible
Dependents: scheduler-demo-cq-lpc11u35 scheduler-demo scheduler-demo-cq-lpc11u35 mbed-scli-test
Scheduler.cpp@1:8967b575bb46, 2013-08-25 (annotated)
- Committer:
- mimi3
- Date:
- Sun Aug 25 10:25:11 2013 +0000
- Revision:
- 1:8967b575bb46
- Parent:
- 0:c68459544a17
For LPC1114FN28.; Scheduler library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dinau | 0:c68459544a17 | 1 | /* |
mimi3 | 1:8967b575bb46 | 2 | * Copyright (C) 2012-2013 audin |
dinau | 0:c68459544a17 | 3 | * This program is licensed under the Apache License, Version 2.0. |
mimi3 | 1:8967b575bb46 | 4 | * 2013/08: Modify for mbed for LPC1114FN28 |
dinau | 0:c68459544a17 | 5 | * Modified 2012/10: For working on Cortex-M0 and M3. |
dinau | 0:c68459544a17 | 6 | * Defined static tcb option for the cpu that has quite a less SRAM < 8kbyte. |
dinau | 0:c68459544a17 | 7 | * |
dinau | 0:c68459544a17 | 8 | * Original file is arduino-1.5\hardware\arduino\sam\libraries\Scheduler |
dinau | 0:c68459544a17 | 9 | */ |
dinau | 0:c68459544a17 | 10 | |
dinau | 0:c68459544a17 | 11 | /* |
dinau | 0:c68459544a17 | 12 | * Copyright (C) 2012 The Android Open Source Project |
dinau | 0:c68459544a17 | 13 | * |
dinau | 0:c68459544a17 | 14 | * Licensed under the Apache License, Version 2.0 (the "License"); |
dinau | 0:c68459544a17 | 15 | * you may not use this file except in compliance with the License. |
dinau | 0:c68459544a17 | 16 | * You may obtain a copy of the License at |
dinau | 0:c68459544a17 | 17 | * |
dinau | 0:c68459544a17 | 18 | * http://www.apache.org/licenses/LICENSE-2.0 |
dinau | 0:c68459544a17 | 19 | * |
dinau | 0:c68459544a17 | 20 | * Unless required by applicable law or agreed to in writing, software |
dinau | 0:c68459544a17 | 21 | * distributed under the License is distributed on an "AS IS" BASIS, |
dinau | 0:c68459544a17 | 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
dinau | 0:c68459544a17 | 23 | * See the License for the specific language governing permissions and |
dinau | 0:c68459544a17 | 24 | * limitations under the License. |
dinau | 0:c68459544a17 | 25 | */ |
dinau | 0:c68459544a17 | 26 | |
dinau | 0:c68459544a17 | 27 | #include <stdint.h> |
mimi3 | 1:8967b575bb46 | 28 | #include "mbed.h" |
dinau | 0:c68459544a17 | 29 | #include "Scheduler.h" |
dinau | 0:c68459544a17 | 30 | |
dinau | 0:c68459544a17 | 31 | #define _ARM_CM0_ 1 /* 1: Cortex-M0 or M3, 0: Cortex-M3 */ |
dinau | 0:c68459544a17 | 32 | #define _USE_MALLOC_ 0 /* 1: 8kbyte >= SRAM, 0: 8kbyte < SRAM */ |
dinau | 0:c68459544a17 | 33 | |
dinau | 0:c68459544a17 | 34 | |
dinau | 0:c68459544a17 | 35 | #if _USE_MALLOC_ |
dinau | 0:c68459544a17 | 36 | # include <stdlib.h> |
dinau | 0:c68459544a17 | 37 | #endif |
dinau | 0:c68459544a17 | 38 | |
dinau | 0:c68459544a17 | 39 | #ifdef __cplusplus |
dinau | 0:c68459544a17 | 40 | extern "C" { |
dinau | 0:c68459544a17 | 41 | #endif |
dinau | 0:c68459544a17 | 42 | uint32_t millis(void); |
dinau | 0:c68459544a17 | 43 | |
dinau | 0:c68459544a17 | 44 | #define NUM_REGS 10 // r4-r11, sp, lr |
dinau | 0:c68459544a17 | 45 | |
dinau | 0:c68459544a17 | 46 | typedef struct CoopTask { |
dinau | 0:c68459544a17 | 47 | uint32_t regs[NUM_REGS]; |
dinau | 0:c68459544a17 | 48 | void* stackPtr; |
dinau | 0:c68459544a17 | 49 | struct CoopTask* next; |
dinau | 0:c68459544a17 | 50 | struct CoopTask* prev; |
dinau | 0:c68459544a17 | 51 | } CoopTask; |
dinau | 0:c68459544a17 | 52 | |
dinau | 0:c68459544a17 | 53 | #if !_USE_MALLOC_ |
dinau | 0:c68459544a17 | 54 | static uint32_t id = 0; |
dinau | 0:c68459544a17 | 55 | static CoopTask tcb[ COOP_TASK_NUM_MAX ]; |
dinau | 0:c68459544a17 | 56 | static uint8_t task_stack[ COOP_TASK_NUM_MAX - 1 ][ MIN_STACK_SIZE ]; |
dinau | 0:c68459544a17 | 57 | #endif |
dinau | 0:c68459544a17 | 58 | |
dinau | 0:c68459544a17 | 59 | static CoopTask *cur = 0; |
dinau | 0:c68459544a17 | 60 | |
dinau | 0:c68459544a17 | 61 | CoopTask* __attribute__((noinline)) coopSchedule(char taskDied) { |
dinau | 0:c68459544a17 | 62 | CoopTask* next = cur->next; |
dinau | 0:c68459544a17 | 63 | |
dinau | 0:c68459544a17 | 64 | #if _USE_MALLOC_ |
dinau | 0:c68459544a17 | 65 | if (taskDied) { |
dinau | 0:c68459544a17 | 66 | // Halt if last task died. |
dinau | 0:c68459544a17 | 67 | if (next == cur) |
dinau | 0:c68459544a17 | 68 | while (1) |
dinau | 0:c68459544a17 | 69 | ; |
dinau | 0:c68459544a17 | 70 | |
dinau | 0:c68459544a17 | 71 | // Delete task |
dinau | 0:c68459544a17 | 72 | if (cur->stackPtr) |
dinau | 0:c68459544a17 | 73 | free(cur->stackPtr); |
dinau | 0:c68459544a17 | 74 | cur->next->prev = cur->prev; |
dinau | 0:c68459544a17 | 75 | cur->prev->next = cur->next; |
dinau | 0:c68459544a17 | 76 | free(cur); |
dinau | 0:c68459544a17 | 77 | } |
dinau | 0:c68459544a17 | 78 | #endif |
dinau | 0:c68459544a17 | 79 | cur = next; |
dinau | 0:c68459544a17 | 80 | return next; |
dinau | 0:c68459544a17 | 81 | } |
mimi3 | 1:8967b575bb46 | 82 | #ifdef __CC_ARM |
mimi3 | 1:8967b575bb46 | 83 | __asm static void coopTaskStart(void) { |
mimi3 | 1:8967b575bb46 | 84 | import coopSchedule |
mimi3 | 1:8967b575bb46 | 85 | #if _ARM_CM0_ |
mimi3 | 1:8967b575bb46 | 86 | /* for Cortex-m0 */ |
mimi3 | 1:8967b575bb46 | 87 | mov r0, r5; |
mimi3 | 1:8967b575bb46 | 88 | blx r4; |
mimi3 | 1:8967b575bb46 | 89 | movs r0, #1; |
mimi3 | 1:8967b575bb46 | 90 | bl coopSchedule; |
mimi3 | 1:8967b575bb46 | 91 | /**** ldmia r0, {r4-r12, lr}; */ |
mimi3 | 1:8967b575bb46 | 92 | adds r0, r0, #16; |
mimi3 | 1:8967b575bb46 | 93 | ldmia r0!, {r4-r7}; /* get r7->r11, r6->r10, r5->r9, r4->r8 */ |
mimi3 | 1:8967b575bb46 | 94 | mov r11, r7; |
mimi3 | 1:8967b575bb46 | 95 | mov r10, r6; |
mimi3 | 1:8967b575bb46 | 96 | mov r9, r5; |
mimi3 | 1:8967b575bb46 | 97 | mov r8 , r4; |
dinau | 0:c68459544a17 | 98 | |
mimi3 | 1:8967b575bb46 | 99 | ldmia r0!, {r4-r5}; /* get r5->lr, r4->r12 */ |
mimi3 | 1:8967b575bb46 | 100 | mov lr, r5; |
mimi3 | 1:8967b575bb46 | 101 | mov r12, r4; |
mimi3 | 1:8967b575bb46 | 102 | |
mimi3 | 1:8967b575bb46 | 103 | subs r0, r0, #40; /* set offset for r4, 40 = 10reg * 4byte */ |
mimi3 | 1:8967b575bb46 | 104 | ldmia r0!, {r4-r7}; /* get r7,r6,r5,r4 */ |
mimi3 | 1:8967b575bb46 | 105 | /**** end ldmia converted by Cortex-M0 instructions */ |
mimi3 | 1:8967b575bb46 | 106 | msr msp, r12; /* use main stack */ |
mimi3 | 1:8967b575bb46 | 107 | bx lr; |
mimi3 | 1:8967b575bb46 | 108 | #else |
mimi3 | 1:8967b575bb46 | 109 | /* for Cortex-m3 or ARM code cpu */ |
mimi3 | 1:8967b575bb46 | 110 | mov r0, r5; /* r5 = new task func */ |
mimi3 | 1:8967b575bb46 | 111 | blx r4; /* r4 = helper func */ |
mimi3 | 1:8967b575bb46 | 112 | movs r0, #1; |
mimi3 | 1:8967b575bb46 | 113 | bl coopSchedule; |
mimi3 | 1:8967b575bb46 | 114 | ldmia r0, {r4-r12, lr}; |
mimi3 | 1:8967b575bb46 | 115 | mov sp, r12; |
mimi3 | 1:8967b575bb46 | 116 | bx lr; |
mimi3 | 1:8967b575bb46 | 117 | #endif |
mimi3 | 1:8967b575bb46 | 118 | } |
mimi3 | 1:8967b575bb46 | 119 | #else |
dinau | 0:c68459544a17 | 120 | static void __attribute__((naked)) __attribute__((noinline)) coopTaskStart(void) { |
dinau | 0:c68459544a17 | 121 | #if _ARM_CM0_ |
dinau | 0:c68459544a17 | 122 | /* for Cortex-m0 */ |
dinau | 0:c68459544a17 | 123 | __asm ( |
dinau | 0:c68459544a17 | 124 | "mov r0, r5;" |
dinau | 0:c68459544a17 | 125 | "blx r4;" |
dinau | 0:c68459544a17 | 126 | "mov r0, #1;" |
dinau | 0:c68459544a17 | 127 | "bl coopSchedule;" |
dinau | 0:c68459544a17 | 128 | /**** "ldmia r0, {r4-r12, lr};" */ |
dinau | 0:c68459544a17 | 129 | "add r0, r0, #16;" |
dinau | 0:c68459544a17 | 130 | "ldmia r0!, {r4-r7};" /* get r7->r11, r6->r10, r5->r9, r4->r8 */ |
dinau | 0:c68459544a17 | 131 | "mov r11, r7;" |
dinau | 0:c68459544a17 | 132 | "mov r10, r6;" |
dinau | 0:c68459544a17 | 133 | "mov r9, r5;" |
dinau | 0:c68459544a17 | 134 | "mov r8 , r4;" |
dinau | 0:c68459544a17 | 135 | |
dinau | 0:c68459544a17 | 136 | "ldmia r0!, {r4-r5};" /* get r5->lr, r4->r12 */ |
dinau | 0:c68459544a17 | 137 | "mov lr, r5;" |
dinau | 0:c68459544a17 | 138 | "mov r12, r4;" |
dinau | 0:c68459544a17 | 139 | |
dinau | 0:c68459544a17 | 140 | "sub r0, r0, #40;" /* set offset for r4, 40 = 10reg * 4byte */ |
dinau | 0:c68459544a17 | 141 | "ldmia r0!, {r4-r7};" /* get r7,r6,r5,r4 */ |
dinau | 0:c68459544a17 | 142 | /**** end ldmia converted by Cortex-M0 instructions */ |
dinau | 0:c68459544a17 | 143 | "msr msp, r12;" /* use main stack */ |
dinau | 0:c68459544a17 | 144 | "bx lr;" |
dinau | 0:c68459544a17 | 145 | ); |
dinau | 0:c68459544a17 | 146 | #else |
dinau | 0:c68459544a17 | 147 | /* for Cortex-m3 or ARM code cpu */ |
dinau | 0:c68459544a17 | 148 | asm ( |
dinau | 0:c68459544a17 | 149 | "mov r0, r5;" /* r5 = new task func */ |
dinau | 0:c68459544a17 | 150 | "blx r4;" /* r4 = helper func */ |
dinau | 0:c68459544a17 | 151 | "mov r0, #1;" |
dinau | 0:c68459544a17 | 152 | "bl coopSchedule;" |
dinau | 0:c68459544a17 | 153 | "ldmia r0, {r4-r12, lr};" |
dinau | 0:c68459544a17 | 154 | "mov sp, r12;" |
dinau | 0:c68459544a17 | 155 | "bx lr;" |
dinau | 0:c68459544a17 | 156 | ); |
dinau | 0:c68459544a17 | 157 | #endif |
dinau | 0:c68459544a17 | 158 | } |
mimi3 | 1:8967b575bb46 | 159 | #endif |
dinau | 0:c68459544a17 | 160 | |
mimi3 | 1:8967b575bb46 | 161 | #ifdef __CC_ARM |
mimi3 | 1:8967b575bb46 | 162 | __asm static void coopDoYield(CoopTask* curTask) { |
mimi3 | 1:8967b575bb46 | 163 | #if _ARM_CM0_ |
mimi3 | 1:8967b575bb46 | 164 | /* for Cortex-m0 */ |
mimi3 | 1:8967b575bb46 | 165 | mrs r12, msp; |
mimi3 | 1:8967b575bb46 | 166 | /**** stmia r0, {r4-r12, lr}; */ |
mimi3 | 1:8967b575bb46 | 167 | stmia r0!, {r4-r7}; /* first store r4-r7 data */ |
mimi3 | 1:8967b575bb46 | 168 | |
mimi3 | 1:8967b575bb46 | 169 | mov r4, r8; |
mimi3 | 1:8967b575bb46 | 170 | mov r5, r9; |
mimi3 | 1:8967b575bb46 | 171 | mov r6, r10; |
mimi3 | 1:8967b575bb46 | 172 | mov r7, r11; |
mimi3 | 1:8967b575bb46 | 173 | stmia r0!, {r4-r7}; /* store r8-r11 */ |
mimi3 | 1:8967b575bb46 | 174 | |
mimi3 | 1:8967b575bb46 | 175 | mov r4, r12; |
mimi3 | 1:8967b575bb46 | 176 | mov r5, lr; |
mimi3 | 1:8967b575bb46 | 177 | stmia r0!, {r4,r5}; /* store r12, lr */ |
mimi3 | 1:8967b575bb46 | 178 | /**** end stmia converted by cortex-m0 instructions */ |
mimi3 | 1:8967b575bb46 | 179 | |
mimi3 | 1:8967b575bb46 | 180 | movs r0, #0; |
mimi3 | 1:8967b575bb46 | 181 | bl coopSchedule; |
mimi3 | 1:8967b575bb46 | 182 | |
mimi3 | 1:8967b575bb46 | 183 | /**** ldmia r0, {r4-r12, lr}; */ |
mimi3 | 1:8967b575bb46 | 184 | adds r0, r0, #16; /* set offset for r8 */ |
mimi3 | 1:8967b575bb46 | 185 | ldmia r0!, {r4-r7}; /* get r7->r11, r6->r10, r5->r9, r4->r8 */ |
mimi3 | 1:8967b575bb46 | 186 | mov r11, r7; |
mimi3 | 1:8967b575bb46 | 187 | mov r10, r6; |
mimi3 | 1:8967b575bb46 | 188 | mov r9, r5; |
mimi3 | 1:8967b575bb46 | 189 | mov r8 , r4; |
mimi3 | 1:8967b575bb46 | 190 | |
mimi3 | 1:8967b575bb46 | 191 | ldmia r0!, {r4-r5}; /* get r5->lr, r4->r12 */ |
mimi3 | 1:8967b575bb46 | 192 | mov lr, r5; |
mimi3 | 1:8967b575bb46 | 193 | mov r12, r4; |
mimi3 | 1:8967b575bb46 | 194 | |
mimi3 | 1:8967b575bb46 | 195 | subs r0, r0, #40; /* set offset for r4, 40 = 10reg * 4byte */ |
mimi3 | 1:8967b575bb46 | 196 | ldmia r0!, {r4-r7}; |
mimi3 | 1:8967b575bb46 | 197 | /**** end ldmia converted by Cortex-M0 instructions */ |
mimi3 | 1:8967b575bb46 | 198 | |
mimi3 | 1:8967b575bb46 | 199 | msr msp, r12; |
mimi3 | 1:8967b575bb46 | 200 | bx lr; |
mimi3 | 1:8967b575bb46 | 201 | #else |
mimi3 | 1:8967b575bb46 | 202 | /* for Cortex-m3 or ARM code cpu */ |
mimi3 | 1:8967b575bb46 | 203 | mov r12, sp; |
mimi3 | 1:8967b575bb46 | 204 | stmia r0, {r4-r12, lr}; |
mimi3 | 1:8967b575bb46 | 205 | movs r0, #0; |
mimi3 | 1:8967b575bb46 | 206 | bl coopSchedule; |
mimi3 | 1:8967b575bb46 | 207 | ldmia r0, {r4-r12, lr}; |
mimi3 | 1:8967b575bb46 | 208 | mov sp, r12; |
mimi3 | 1:8967b575bb46 | 209 | bx lr; |
mimi3 | 1:8967b575bb46 | 210 | #endif |
mimi3 | 1:8967b575bb46 | 211 | } |
mimi3 | 1:8967b575bb46 | 212 | |
mimi3 | 1:8967b575bb46 | 213 | #else |
dinau | 0:c68459544a17 | 214 | static void __attribute__((naked)) __attribute__((noinline)) coopDoYield(CoopTask* curTask) { |
dinau | 0:c68459544a17 | 215 | #if _ARM_CM0_ |
dinau | 0:c68459544a17 | 216 | /* for Cortex-m0 */ |
dinau | 0:c68459544a17 | 217 | __asm ( |
dinau | 0:c68459544a17 | 218 | "mrs r12, msp;" |
dinau | 0:c68459544a17 | 219 | /**** "stmia r0, {r4-r12, lr};" */ |
dinau | 0:c68459544a17 | 220 | "stmia r0!, {r4-r7};" /* first store r4-r7 data */ |
dinau | 0:c68459544a17 | 221 | |
dinau | 0:c68459544a17 | 222 | "mov r4, r8;" |
dinau | 0:c68459544a17 | 223 | "mov r5, r9;" |
dinau | 0:c68459544a17 | 224 | "mov r6, r10;" |
dinau | 0:c68459544a17 | 225 | "mov r7, r11;" |
dinau | 0:c68459544a17 | 226 | "stmia r0!, {r4-r7};" /* store r8-r11 */ |
dinau | 0:c68459544a17 | 227 | |
dinau | 0:c68459544a17 | 228 | "mov r4, r12;" |
dinau | 0:c68459544a17 | 229 | "mov r5, lr;" |
dinau | 0:c68459544a17 | 230 | "stmia r0!, {r4,r5};" /* store r12, lr */ |
dinau | 0:c68459544a17 | 231 | /**** end stmia converted by cortex-m0 instructions */ |
dinau | 0:c68459544a17 | 232 | |
dinau | 0:c68459544a17 | 233 | "mov r0, #0;" |
dinau | 0:c68459544a17 | 234 | "bl coopSchedule;" |
dinau | 0:c68459544a17 | 235 | |
dinau | 0:c68459544a17 | 236 | /**** "ldmia r0, {r4-r12, lr};" */ |
dinau | 0:c68459544a17 | 237 | "add r0, r0, #16;" /* set offset for r8 */ |
dinau | 0:c68459544a17 | 238 | "ldmia r0!, {r4-r7};" /* get r7->r11, r6->r10, r5->r9, r4->r8 */ |
dinau | 0:c68459544a17 | 239 | "mov r11, r7;" |
dinau | 0:c68459544a17 | 240 | "mov r10, r6;" |
dinau | 0:c68459544a17 | 241 | "mov r9, r5;" |
dinau | 0:c68459544a17 | 242 | "mov r8 , r4;" |
dinau | 0:c68459544a17 | 243 | |
dinau | 0:c68459544a17 | 244 | "ldmia r0!, {r4-r5};" /* get r5->lr, r4->r12 */ |
dinau | 0:c68459544a17 | 245 | "mov lr, r5;" |
dinau | 0:c68459544a17 | 246 | "mov r12, r4;" |
dinau | 0:c68459544a17 | 247 | |
dinau | 0:c68459544a17 | 248 | "sub r0, r0, #40;" /* set offset for r4, 40 = 10reg * 4byte */ |
dinau | 0:c68459544a17 | 249 | "ldmia r0!, {r4-r7};" |
dinau | 0:c68459544a17 | 250 | /**** end ldmia converted by Cortex-M0 instructions */ |
dinau | 0:c68459544a17 | 251 | |
dinau | 0:c68459544a17 | 252 | "msr msp, r12;" |
dinau | 0:c68459544a17 | 253 | "bx lr;" |
dinau | 0:c68459544a17 | 254 | ); |
dinau | 0:c68459544a17 | 255 | #else |
dinau | 0:c68459544a17 | 256 | /* for Cortex-m3 or ARM code cpu */ |
dinau | 0:c68459544a17 | 257 | __asm ( |
dinau | 0:c68459544a17 | 258 | "mov r12, sp;" |
dinau | 0:c68459544a17 | 259 | "stmia r0, {r4-r12, lr};" |
dinau | 0:c68459544a17 | 260 | "mov r0, #0;" |
dinau | 0:c68459544a17 | 261 | "bl coopSchedule;" |
dinau | 0:c68459544a17 | 262 | "ldmia r0, {r4-r12, lr};" |
dinau | 0:c68459544a17 | 263 | "mov sp, r12;" |
dinau | 0:c68459544a17 | 264 | "bx lr;" |
dinau | 0:c68459544a17 | 265 | ); |
dinau | 0:c68459544a17 | 266 | #endif |
dinau | 0:c68459544a17 | 267 | |
dinau | 0:c68459544a17 | 268 | } |
mimi3 | 1:8967b575bb46 | 269 | #endif |
dinau | 0:c68459544a17 | 270 | static int coopInit(void) { |
dinau | 0:c68459544a17 | 271 | CoopTask* task; |
dinau | 0:c68459544a17 | 272 | #if _USE_MALLOC_ |
dinau | 0:c68459544a17 | 273 | # ifdef __cplusplus |
dinau | 0:c68459544a17 | 274 | task = reinterpret_cast<CoopTask *>(malloc(sizeof(CoopTask))); |
dinau | 0:c68459544a17 | 275 | # else |
dinau | 0:c68459544a17 | 276 | task = (CoopTask *)(malloc(sizeof(CoopTask))); |
dinau | 0:c68459544a17 | 277 | # endif |
dinau | 0:c68459544a17 | 278 | if (!task) |
dinau | 0:c68459544a17 | 279 | return 0; |
dinau | 0:c68459544a17 | 280 | #else |
dinau | 0:c68459544a17 | 281 | task = &tcb[ id ]; |
dinau | 0:c68459544a17 | 282 | #endif |
dinau | 0:c68459544a17 | 283 | task->next = task; |
dinau | 0:c68459544a17 | 284 | task->prev = task; |
dinau | 0:c68459544a17 | 285 | task->stackPtr = 0; |
dinau | 0:c68459544a17 | 286 | cur = task; |
dinau | 0:c68459544a17 | 287 | |
dinau | 0:c68459544a17 | 288 | return 1; |
dinau | 0:c68459544a17 | 289 | } |
dinau | 0:c68459544a17 | 290 | |
dinau | 0:c68459544a17 | 291 | static int coopSpawn(SchedulerParametricTask taskF, void* taskData, uint32_t stackSz) { |
dinau | 0:c68459544a17 | 292 | #if _USE_MALLOC_ |
dinau | 0:c68459544a17 | 293 | uint8_t *stack = (uint8_t*)malloc(stackSz); |
dinau | 0:c68459544a17 | 294 | if (!stack) |
dinau | 0:c68459544a17 | 295 | return 0; |
dinau | 0:c68459544a17 | 296 | # ifdef __cplusplus |
dinau | 0:c68459544a17 | 297 | CoopTask *task = reinterpret_cast<CoopTask *>(malloc(sizeof(CoopTask))); |
dinau | 0:c68459544a17 | 298 | # else |
dinau | 0:c68459544a17 | 299 | CoopTask *task = (CoopTask *)(malloc(sizeof(CoopTask))); |
dinau | 0:c68459544a17 | 300 | # endif |
dinau | 0:c68459544a17 | 301 | if (!task) { |
dinau | 0:c68459544a17 | 302 | free(stack); |
dinau | 0:c68459544a17 | 303 | return 0; |
dinau | 0:c68459544a17 | 304 | } |
dinau | 0:c68459544a17 | 305 | #else |
dinau | 0:c68459544a17 | 306 | uint8_t *stack = task_stack[ id ]; |
dinau | 0:c68459544a17 | 307 | id++; |
dinau | 0:c68459544a17 | 308 | CoopTask *task = &tcb[ id ]; |
dinau | 0:c68459544a17 | 309 | #endif |
dinau | 0:c68459544a17 | 310 | task->stackPtr = stack; |
dinau | 0:c68459544a17 | 311 | task->regs[0] = (uint32_t) taskF; /* Helper func: r4 */ |
dinau | 0:c68459544a17 | 312 | task->regs[1] = (uint32_t) taskData; /* New task : r5 */ |
dinau | 0:c68459544a17 | 313 | #if _USE_MALLOC_ |
dinau | 0:c68459544a17 | 314 | task->regs[8] = ((uint32_t)(stack + stackSz)) & ~7; |
dinau | 0:c68459544a17 | 315 | #else |
dinau | 0:c68459544a17 | 316 | task->regs[8] = ((uint32_t)(stack + MIN_STACK_SIZE)) & ~7; /* r12 */ |
dinau | 0:c68459544a17 | 317 | #endif |
dinau | 0:c68459544a17 | 318 | task->regs[9] = (uint32_t) & coopTaskStart; /* lr */ |
dinau | 0:c68459544a17 | 319 | |
dinau | 0:c68459544a17 | 320 | task->prev = cur; |
dinau | 0:c68459544a17 | 321 | task->next = cur->next; |
dinau | 0:c68459544a17 | 322 | cur->next->prev = task; |
dinau | 0:c68459544a17 | 323 | cur->next = task; |
dinau | 0:c68459544a17 | 324 | |
dinau | 0:c68459544a17 | 325 | // These are here so compiler is sure that function is |
dinau | 0:c68459544a17 | 326 | // referenced in both variants (cancels a warning) |
dinau | 0:c68459544a17 | 327 | if (stackSz == 0xFFFFFFFF) |
dinau | 0:c68459544a17 | 328 | coopSchedule(0); |
dinau | 0:c68459544a17 | 329 | if (stackSz == 0xFFFFFFFE) |
dinau | 0:c68459544a17 | 330 | coopSchedule(1); |
dinau | 0:c68459544a17 | 331 | |
dinau | 0:c68459544a17 | 332 | return 1; |
dinau | 0:c68459544a17 | 333 | } |
dinau | 0:c68459544a17 | 334 | |
dinau | 0:c68459544a17 | 335 | void yield(void) { |
dinau | 0:c68459544a17 | 336 | coopDoYield(cur); |
dinau | 0:c68459544a17 | 337 | } |
dinau | 0:c68459544a17 | 338 | |
mimi3 | 1:8967b575bb46 | 339 | #ifdef MBED_H |
mimi3 | 1:8967b575bb46 | 340 | void taskWait(uint32_t ms) { |
mimi3 | 1:8967b575bb46 | 341 | uint32_t start = us_ticker_read(); |
mimi3 | 1:8967b575bb46 | 342 | while ((us_ticker_read() - start) < (uint32_t)(ms*1000)){ |
mimi3 | 1:8967b575bb46 | 343 | yield(); |
mimi3 | 1:8967b575bb46 | 344 | } |
mimi3 | 1:8967b575bb46 | 345 | } |
mimi3 | 1:8967b575bb46 | 346 | #else |
dinau | 0:c68459544a17 | 347 | void wait(uint32_t ms) { |
dinau | 0:c68459544a17 | 348 | uint32_t start = millis(); |
mimi3 | 1:8967b575bb46 | 349 | while (millis() - start < ms){ |
dinau | 0:c68459544a17 | 350 | yield(); |
mimi3 | 1:8967b575bb46 | 351 | } |
dinau | 0:c68459544a17 | 352 | } |
mimi3 | 1:8967b575bb46 | 353 | #endif |
dinau | 0:c68459544a17 | 354 | |
dinau | 0:c68459544a17 | 355 | #ifdef __cplusplus |
dinau | 0:c68459544a17 | 356 | }; // extern "C" |
dinau | 0:c68459544a17 | 357 | #endif |
dinau | 0:c68459544a17 | 358 | |
dinau | 0:c68459544a17 | 359 | void scheduler_init( void ) { |
dinau | 0:c68459544a17 | 360 | coopInit(); |
dinau | 0:c68459544a17 | 361 | } |
dinau | 0:c68459544a17 | 362 | |
dinau | 0:c68459544a17 | 363 | static void startLoopHelper(void *taskData) { |
dinau | 0:c68459544a17 | 364 | #ifdef __cplusplus |
dinau | 0:c68459544a17 | 365 | SchedulerTask task = reinterpret_cast<SchedulerTask>(taskData); |
dinau | 0:c68459544a17 | 366 | #else |
dinau | 0:c68459544a17 | 367 | SchedulerTask task = (SchedulerTask)(taskData); |
dinau | 0:c68459544a17 | 368 | #endif |
dinau | 0:c68459544a17 | 369 | while (1){ |
dinau | 0:c68459544a17 | 370 | task(); |
dinau | 0:c68459544a17 | 371 | } |
dinau | 0:c68459544a17 | 372 | } |
dinau | 0:c68459544a17 | 373 | |
dinau | 0:c68459544a17 | 374 | static void startTaskHelper(void *taskData) { |
dinau | 0:c68459544a17 | 375 | #ifdef __cplusplus |
dinau | 0:c68459544a17 | 376 | SchedulerTask task = reinterpret_cast<SchedulerTask>(taskData); |
dinau | 0:c68459544a17 | 377 | #else |
dinau | 0:c68459544a17 | 378 | SchedulerTask task = (SchedulerTask)(taskData); |
dinau | 0:c68459544a17 | 379 | #endif |
dinau | 0:c68459544a17 | 380 | task(); |
dinau | 0:c68459544a17 | 381 | } |
dinau | 0:c68459544a17 | 382 | |
dinau | 0:c68459544a17 | 383 | void scheduler_start( SchedulerTask task ) { |
dinau | 0:c68459544a17 | 384 | coopSpawn( startTaskHelper, (void *)(task), MIN_STACK_SIZE ); |
dinau | 0:c68459544a17 | 385 | } |
dinau | 0:c68459544a17 | 386 | |
dinau | 0:c68459544a17 | 387 | void scheduler_startLoop( SchedulerTask task) { |
dinau | 0:c68459544a17 | 388 | coopSpawn( startLoopHelper, (void *)(task), MIN_STACK_SIZE ); |
dinau | 0:c68459544a17 | 389 | } |
dinau | 0:c68459544a17 | 390 | |
dinau | 0:c68459544a17 | 391 | #ifdef __cplusplus |
dinau | 0:c68459544a17 | 392 | SchedulerClass::SchedulerClass() { |
dinau | 0:c68459544a17 | 393 | coopInit(); |
dinau | 0:c68459544a17 | 394 | } |
dinau | 0:c68459544a17 | 395 | |
dinau | 0:c68459544a17 | 396 | void SchedulerClass::startLoop(SchedulerTask task, uint32_t stackSize) { |
dinau | 0:c68459544a17 | 397 | coopSpawn(startLoopHelper, reinterpret_cast<void *>(task), stackSize); |
dinau | 0:c68459544a17 | 398 | } |
dinau | 0:c68459544a17 | 399 | |
dinau | 0:c68459544a17 | 400 | void SchedulerClass::start(SchedulerTask task, uint32_t stackSize) { |
dinau | 0:c68459544a17 | 401 | coopSpawn(startTaskHelper, reinterpret_cast<void *>(task), stackSize); |
dinau | 0:c68459544a17 | 402 | } |
dinau | 0:c68459544a17 | 403 | |
dinau | 0:c68459544a17 | 404 | void SchedulerClass::start(SchedulerParametricTask task, void *taskData, uint32_t stackSize) { |
dinau | 0:c68459544a17 | 405 | coopSpawn(task, taskData, stackSize); |
dinau | 0:c68459544a17 | 406 | } |
dinau | 0:c68459544a17 | 407 | |
dinau | 0:c68459544a17 | 408 | SchedulerClass Scheduler; |
dinau | 0:c68459544a17 | 409 | #endif |
dinau | 0:c68459544a17 | 410 |