https://github.com/WebBluetoothCG/demos/pull/42

Dependencies:   BLE_API mbed-dev-bin nRF51822

Fork of microbit-dal by Lancaster University

Committer:
Jonathan Austin
Date:
Thu Apr 07 01:33:22 2016 +0100
Revision:
1:8aa5cdb4ab67
Child:
41:da05ec75cd5d
Synchronized with git rev 55cb9199

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Functionality definitions for the MicroBit Fiber scheduler.
Jonathan Austin 1:8aa5cdb4ab67 28 *
Jonathan Austin 1:8aa5cdb4ab67 29 * This lightweight, non-preemptive scheduler provides a simple threading mechanism for two main purposes:
Jonathan Austin 1:8aa5cdb4ab67 30 *
Jonathan Austin 1:8aa5cdb4ab67 31 * 1) To provide a clean abstraction for application languages to use when building async behaviour (callbacks).
Jonathan Austin 1:8aa5cdb4ab67 32 * 2) To provide ISR decoupling for EventModel events generated in an ISR context.
Jonathan Austin 1:8aa5cdb4ab67 33 *
Jonathan Austin 1:8aa5cdb4ab67 34 * TODO: Consider a split mode scheduler, that monitors used stack size, and maintains a dedicated, persistent
Jonathan Austin 1:8aa5cdb4ab67 35 * stack for any long lived fibers with large stack
Jonathan Austin 1:8aa5cdb4ab67 36 */
Jonathan Austin 1:8aa5cdb4ab67 37 #ifndef MICROBIT_FIBER_H
Jonathan Austin 1:8aa5cdb4ab67 38 #define MICROBIT_FIBER_H
Jonathan Austin 1:8aa5cdb4ab67 39
Jonathan Austin 1:8aa5cdb4ab67 40 #include "mbed.h"
Jonathan Austin 1:8aa5cdb4ab67 41 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 42 #include "MicroBitEvent.h"
Jonathan Austin 1:8aa5cdb4ab67 43 #include "EventModel.h"
Jonathan Austin 1:8aa5cdb4ab67 44
Jonathan Austin 1:8aa5cdb4ab67 45 // Fiber Scheduler Flags
Jonathan Austin 1:8aa5cdb4ab67 46 #define MICROBIT_SCHEDULER_RUNNING 0x01
Jonathan Austin 1:8aa5cdb4ab67 47
Jonathan Austin 1:8aa5cdb4ab67 48 // Fiber Flags
Jonathan Austin 1:8aa5cdb4ab67 49 #define MICROBIT_FIBER_FLAG_FOB 0x01
Jonathan Austin 1:8aa5cdb4ab67 50 #define MICROBIT_FIBER_FLAG_PARENT 0x02
Jonathan Austin 1:8aa5cdb4ab67 51 #define MICROBIT_FIBER_FLAG_CHILD 0x04
Jonathan Austin 1:8aa5cdb4ab67 52 #define MICROBIT_FIBER_FLAG_DO_NOT_PAGE 0x08
Jonathan Austin 1:8aa5cdb4ab67 53
Jonathan Austin 1:8aa5cdb4ab67 54 /**
Jonathan Austin 1:8aa5cdb4ab67 55 * Thread Context for an ARM Cortex M0 core.
Jonathan Austin 1:8aa5cdb4ab67 56 *
Jonathan Austin 1:8aa5cdb4ab67 57 * This is probably overkill, but the ARMCC compiler uses a lot register optimisation
Jonathan Austin 1:8aa5cdb4ab67 58 * in its calling conventions, so better safe than sorry!
Jonathan Austin 1:8aa5cdb4ab67 59 */
Jonathan Austin 1:8aa5cdb4ab67 60 struct Cortex_M0_TCB
Jonathan Austin 1:8aa5cdb4ab67 61 {
Jonathan Austin 1:8aa5cdb4ab67 62 uint32_t R0;
Jonathan Austin 1:8aa5cdb4ab67 63 uint32_t R1;
Jonathan Austin 1:8aa5cdb4ab67 64 uint32_t R2;
Jonathan Austin 1:8aa5cdb4ab67 65 uint32_t R3;
Jonathan Austin 1:8aa5cdb4ab67 66 uint32_t R4;
Jonathan Austin 1:8aa5cdb4ab67 67 uint32_t R5;
Jonathan Austin 1:8aa5cdb4ab67 68 uint32_t R6;
Jonathan Austin 1:8aa5cdb4ab67 69 uint32_t R7;
Jonathan Austin 1:8aa5cdb4ab67 70 uint32_t R8;
Jonathan Austin 1:8aa5cdb4ab67 71 uint32_t R9;
Jonathan Austin 1:8aa5cdb4ab67 72 uint32_t R10;
Jonathan Austin 1:8aa5cdb4ab67 73 uint32_t R11;
Jonathan Austin 1:8aa5cdb4ab67 74 uint32_t R12;
Jonathan Austin 1:8aa5cdb4ab67 75 uint32_t SP;
Jonathan Austin 1:8aa5cdb4ab67 76 uint32_t LR;
Jonathan Austin 1:8aa5cdb4ab67 77 uint32_t stack_base;
Jonathan Austin 1:8aa5cdb4ab67 78 };
Jonathan Austin 1:8aa5cdb4ab67 79
Jonathan Austin 1:8aa5cdb4ab67 80 /**
Jonathan Austin 1:8aa5cdb4ab67 81 * Representation of a single Fiber
Jonathan Austin 1:8aa5cdb4ab67 82 */
Jonathan Austin 1:8aa5cdb4ab67 83 struct Fiber
Jonathan Austin 1:8aa5cdb4ab67 84 {
Jonathan Austin 1:8aa5cdb4ab67 85 Cortex_M0_TCB tcb; // Thread context when last scheduled out.
Jonathan Austin 1:8aa5cdb4ab67 86 uint32_t stack_bottom; // The start address of this Fiber's stack. The stack is heap allocated, and full descending.
Jonathan Austin 1:8aa5cdb4ab67 87 uint32_t stack_top; // The end address of this Fiber's stack.
Jonathan Austin 1:8aa5cdb4ab67 88 uint32_t context; // Context specific information.
Jonathan Austin 1:8aa5cdb4ab67 89 uint32_t flags; // Information about this fiber.
Jonathan Austin 1:8aa5cdb4ab67 90 Fiber **queue; // The queue this fiber is stored on.
Jonathan Austin 1:8aa5cdb4ab67 91 Fiber *next, *prev; // Position of this Fiber on the run queue.
Jonathan Austin 1:8aa5cdb4ab67 92 };
Jonathan Austin 1:8aa5cdb4ab67 93
Jonathan Austin 1:8aa5cdb4ab67 94 extern Fiber *currentFiber;
Jonathan Austin 1:8aa5cdb4ab67 95
Jonathan Austin 1:8aa5cdb4ab67 96
Jonathan Austin 1:8aa5cdb4ab67 97 /**
Jonathan Austin 1:8aa5cdb4ab67 98 * Initialises the Fiber scheduler.
Jonathan Austin 1:8aa5cdb4ab67 99 * Creates a Fiber context around the calling thread, and adds it to the run queue as the current thread.
Jonathan Austin 1:8aa5cdb4ab67 100 *
Jonathan Austin 1:8aa5cdb4ab67 101 * This function must be called once only from the main thread, and before any other Fiber operation.
Jonathan Austin 1:8aa5cdb4ab67 102 *
Jonathan Austin 1:8aa5cdb4ab67 103 * @param _messageBus An event model, used to direct the priorities of the scheduler.
Jonathan Austin 1:8aa5cdb4ab67 104 */
Jonathan Austin 1:8aa5cdb4ab67 105 void scheduler_init(EventModel &_messageBus);
Jonathan Austin 1:8aa5cdb4ab67 106
Jonathan Austin 1:8aa5cdb4ab67 107 /**
Jonathan Austin 1:8aa5cdb4ab67 108 * Determines if the fiber scheduler is operational.
Jonathan Austin 1:8aa5cdb4ab67 109 *
Jonathan Austin 1:8aa5cdb4ab67 110 * @return 1 if the fber scheduler is running, 0 otherwise.
Jonathan Austin 1:8aa5cdb4ab67 111 */
Jonathan Austin 1:8aa5cdb4ab67 112 int fiber_scheduler_running();
Jonathan Austin 1:8aa5cdb4ab67 113
Jonathan Austin 1:8aa5cdb4ab67 114 /**
Jonathan Austin 1:8aa5cdb4ab67 115 * Exit point for all fibers.
Jonathan Austin 1:8aa5cdb4ab67 116 *
Jonathan Austin 1:8aa5cdb4ab67 117 * Any fiber reaching the end of its entry function will return here for recycling.
Jonathan Austin 1:8aa5cdb4ab67 118 */
Jonathan Austin 1:8aa5cdb4ab67 119 void release_fiber(void);
Jonathan Austin 1:8aa5cdb4ab67 120 void release_fiber(void *param);
Jonathan Austin 1:8aa5cdb4ab67 121
Jonathan Austin 1:8aa5cdb4ab67 122 /**
Jonathan Austin 1:8aa5cdb4ab67 123 * Launches a fiber.
Jonathan Austin 1:8aa5cdb4ab67 124 *
Jonathan Austin 1:8aa5cdb4ab67 125 * @param ep the entry point for the fiber.
Jonathan Austin 1:8aa5cdb4ab67 126 *
Jonathan Austin 1:8aa5cdb4ab67 127 * @param cp the completion routine after ep has finished execution
Jonathan Austin 1:8aa5cdb4ab67 128 */
Jonathan Austin 1:8aa5cdb4ab67 129 void launch_new_fiber(void (*ep)(void), void (*cp)(void))
Jonathan Austin 1:8aa5cdb4ab67 130 #ifdef __GCC__
Jonathan Austin 1:8aa5cdb4ab67 131 __attribute__((naked))
Jonathan Austin 1:8aa5cdb4ab67 132 #endif
Jonathan Austin 1:8aa5cdb4ab67 133 ;
Jonathan Austin 1:8aa5cdb4ab67 134
Jonathan Austin 1:8aa5cdb4ab67 135 /**
Jonathan Austin 1:8aa5cdb4ab67 136 * Launches a fiber with a parameter
Jonathan Austin 1:8aa5cdb4ab67 137 *
Jonathan Austin 1:8aa5cdb4ab67 138 * @param ep the entry point for the fiber.
Jonathan Austin 1:8aa5cdb4ab67 139 *
Jonathan Austin 1:8aa5cdb4ab67 140 * @param cp the completion routine after ep has finished execution
Jonathan Austin 1:8aa5cdb4ab67 141 *
Jonathan Austin 1:8aa5cdb4ab67 142 * @param pm the parameter to provide to ep and cp.
Jonathan Austin 1:8aa5cdb4ab67 143 */
Jonathan Austin 1:8aa5cdb4ab67 144 void launch_new_fiber_param(void (*ep)(void *), void (*cp)(void *), void *pm)
Jonathan Austin 1:8aa5cdb4ab67 145 #ifdef __GCC__
Jonathan Austin 1:8aa5cdb4ab67 146 __attribute__((naked))
Jonathan Austin 1:8aa5cdb4ab67 147 #endif
Jonathan Austin 1:8aa5cdb4ab67 148 ;
Jonathan Austin 1:8aa5cdb4ab67 149
Jonathan Austin 1:8aa5cdb4ab67 150 /**
Jonathan Austin 1:8aa5cdb4ab67 151 * Creates a new Fiber, and launches it.
Jonathan Austin 1:8aa5cdb4ab67 152 *
Jonathan Austin 1:8aa5cdb4ab67 153 * @param entry_fn The function the new Fiber will begin execution in.
Jonathan Austin 1:8aa5cdb4ab67 154 *
Jonathan Austin 1:8aa5cdb4ab67 155 * @param completion_fn The function called when the thread completes execution of entry_fn.
Jonathan Austin 1:8aa5cdb4ab67 156 * Defaults to release_fiber.
Jonathan Austin 1:8aa5cdb4ab67 157 *
Jonathan Austin 1:8aa5cdb4ab67 158 * @return The new Fiber, or NULL if the operation could not be completed.
Jonathan Austin 1:8aa5cdb4ab67 159 */
Jonathan Austin 1:8aa5cdb4ab67 160 Fiber *create_fiber(void (*entry_fn)(void), void (*completion_fn)(void) = release_fiber);
Jonathan Austin 1:8aa5cdb4ab67 161
Jonathan Austin 1:8aa5cdb4ab67 162
Jonathan Austin 1:8aa5cdb4ab67 163 /**
Jonathan Austin 1:8aa5cdb4ab67 164 * Creates a new parameterised Fiber, and launches it.
Jonathan Austin 1:8aa5cdb4ab67 165 *
Jonathan Austin 1:8aa5cdb4ab67 166 * @param entry_fn The function the new Fiber will begin execution in.
Jonathan Austin 1:8aa5cdb4ab67 167 *
Jonathan Austin 1:8aa5cdb4ab67 168 * @param param an untyped parameter passed into the entry_fn and completion_fn.
Jonathan Austin 1:8aa5cdb4ab67 169 *
Jonathan Austin 1:8aa5cdb4ab67 170 * @param completion_fn The function called when the thread completes execution of entry_fn.
Jonathan Austin 1:8aa5cdb4ab67 171 * Defaults to release_fiber.
Jonathan Austin 1:8aa5cdb4ab67 172 *
Jonathan Austin 1:8aa5cdb4ab67 173 * @return The new Fiber, or NULL if the operation could not be completed.
Jonathan Austin 1:8aa5cdb4ab67 174 */
Jonathan Austin 1:8aa5cdb4ab67 175 Fiber *create_fiber(void (*entry_fn)(void *), void *param, void (*completion_fn)(void *) = release_fiber);
Jonathan Austin 1:8aa5cdb4ab67 176
Jonathan Austin 1:8aa5cdb4ab67 177
Jonathan Austin 1:8aa5cdb4ab67 178 /**
Jonathan Austin 1:8aa5cdb4ab67 179 * Calls the Fiber scheduler.
Jonathan Austin 1:8aa5cdb4ab67 180 * The calling Fiber will likely be blocked, and control given to another waiting fiber.
Jonathan Austin 1:8aa5cdb4ab67 181 * Call this function to yield control of the processor when you have nothing more to do.
Jonathan Austin 1:8aa5cdb4ab67 182 */
Jonathan Austin 1:8aa5cdb4ab67 183 void schedule();
Jonathan Austin 1:8aa5cdb4ab67 184
Jonathan Austin 1:8aa5cdb4ab67 185 /**
Jonathan Austin 1:8aa5cdb4ab67 186 * Blocks the calling thread for the given period of time.
Jonathan Austin 1:8aa5cdb4ab67 187 * The calling thread will be immediateley descheduled, and placed onto a
Jonathan Austin 1:8aa5cdb4ab67 188 * wait queue until the requested amount of time has elapsed.
Jonathan Austin 1:8aa5cdb4ab67 189 *
Jonathan Austin 1:8aa5cdb4ab67 190 * @param t The period of time to sleep, in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 191 *
Jonathan Austin 1:8aa5cdb4ab67 192 * @note the fiber will not be be made runnable until after the elapsed time, but there
Jonathan Austin 1:8aa5cdb4ab67 193 * are no guarantees precisely when the fiber will next be scheduled.
Jonathan Austin 1:8aa5cdb4ab67 194 */
Jonathan Austin 1:8aa5cdb4ab67 195 void fiber_sleep(unsigned long t);
Jonathan Austin 1:8aa5cdb4ab67 196
Jonathan Austin 1:8aa5cdb4ab67 197 /**
Jonathan Austin 1:8aa5cdb4ab67 198 * The timer callback, called from interrupt context once every SYSTEM_TICK_PERIOD_MS milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 199 * This function checks to determine if any fibers blocked on the sleep queue need to be woken up
Jonathan Austin 1:8aa5cdb4ab67 200 * and made runnable.
Jonathan Austin 1:8aa5cdb4ab67 201 */
Jonathan Austin 1:8aa5cdb4ab67 202 void scheduler_tick();
Jonathan Austin 1:8aa5cdb4ab67 203
Jonathan Austin 1:8aa5cdb4ab67 204 /**
Jonathan Austin 1:8aa5cdb4ab67 205 * Blocks the calling thread until the specified event is raised.
Jonathan Austin 1:8aa5cdb4ab67 206 * The calling thread will be immediateley descheduled, and placed onto a
Jonathan Austin 1:8aa5cdb4ab67 207 * wait queue until the requested event is received.
Jonathan Austin 1:8aa5cdb4ab67 208 *
Jonathan Austin 1:8aa5cdb4ab67 209 * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
Jonathan Austin 1:8aa5cdb4ab67 210 *
Jonathan Austin 1:8aa5cdb4ab67 211 * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
Jonathan Austin 1:8aa5cdb4ab67 212 *
Jonathan Austin 1:8aa5cdb4ab67 213 * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
Jonathan Austin 1:8aa5cdb4ab67 214 *
Jonathan Austin 1:8aa5cdb4ab67 215 * @code
Jonathan Austin 1:8aa5cdb4ab67 216 * fiber_wait_for_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
Jonathan Austin 1:8aa5cdb4ab67 217 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 218 *
Jonathan Austin 1:8aa5cdb4ab67 219 * @note the fiber will not be be made runnable until after the event is raised, but there
Jonathan Austin 1:8aa5cdb4ab67 220 * are no guarantees precisely when the fiber will next be scheduled.
Jonathan Austin 1:8aa5cdb4ab67 221 */
Jonathan Austin 1:8aa5cdb4ab67 222 int fiber_wait_for_event(uint16_t id, uint16_t value);
Jonathan Austin 1:8aa5cdb4ab67 223
Jonathan Austin 1:8aa5cdb4ab67 224 /**
Jonathan Austin 1:8aa5cdb4ab67 225 * Configures the fiber context for the current fiber to block on an event ID
Jonathan Austin 1:8aa5cdb4ab67 226 * and value, but does not deschedule the fiber.
Jonathan Austin 1:8aa5cdb4ab67 227 *
Jonathan Austin 1:8aa5cdb4ab67 228 * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
Jonathan Austin 1:8aa5cdb4ab67 229 *
Jonathan Austin 1:8aa5cdb4ab67 230 * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
Jonathan Austin 1:8aa5cdb4ab67 231 *
Jonathan Austin 1:8aa5cdb4ab67 232 * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
Jonathan Austin 1:8aa5cdb4ab67 233 *
Jonathan Austin 1:8aa5cdb4ab67 234 * @code
Jonathan Austin 1:8aa5cdb4ab67 235 * fiber_wake_on_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
Jonathan Austin 1:8aa5cdb4ab67 236 *
Jonathan Austin 1:8aa5cdb4ab67 237 * //perform some time critical operation.
Jonathan Austin 1:8aa5cdb4ab67 238 *
Jonathan Austin 1:8aa5cdb4ab67 239 * //deschedule the current fiber manually, waiting for the previously configured event.
Jonathan Austin 1:8aa5cdb4ab67 240 * schedule();
Jonathan Austin 1:8aa5cdb4ab67 241 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 242 */
Jonathan Austin 1:8aa5cdb4ab67 243 int fiber_wake_on_event(uint16_t id, uint16_t value);
Jonathan Austin 1:8aa5cdb4ab67 244
Jonathan Austin 1:8aa5cdb4ab67 245 /**
Jonathan Austin 1:8aa5cdb4ab67 246 * Executes the given function asynchronously if necessary.
Jonathan Austin 1:8aa5cdb4ab67 247 *
Jonathan Austin 1:8aa5cdb4ab67 248 * Fibers are often used to run event handlers, however many of these event handlers are very simple functions
Jonathan Austin 1:8aa5cdb4ab67 249 * that complete very quickly, bringing unecessary RAM overhead.
Jonathan Austin 1:8aa5cdb4ab67 250 *
Jonathan Austin 1:8aa5cdb4ab67 251 * This function takes a snapshot of the current processor context, then attempts to optimistically call the given function directly.
Jonathan Austin 1:8aa5cdb4ab67 252 * We only create an additional fiber if that function performs a block operation.
Jonathan Austin 1:8aa5cdb4ab67 253 *
Jonathan Austin 1:8aa5cdb4ab67 254 * @param entry_fn The function to execute.
Jonathan Austin 1:8aa5cdb4ab67 255 *
Jonathan Austin 1:8aa5cdb4ab67 256 * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 257 */
Jonathan Austin 1:8aa5cdb4ab67 258 int invoke(void (*entry_fn)(void));
Jonathan Austin 1:8aa5cdb4ab67 259
Jonathan Austin 1:8aa5cdb4ab67 260 /**
Jonathan Austin 1:8aa5cdb4ab67 261 * Executes the given function asynchronously if necessary, and offers the ability to provide a parameter.
Jonathan Austin 1:8aa5cdb4ab67 262 *
Jonathan Austin 1:8aa5cdb4ab67 263 * Fibers are often used to run event handlers, however many of these event handlers are very simple functions
Jonathan Austin 1:8aa5cdb4ab67 264 * that complete very quickly, bringing unecessary RAM. overhead
Jonathan Austin 1:8aa5cdb4ab67 265 *
Jonathan Austin 1:8aa5cdb4ab67 266 * This function takes a snapshot of the current fiber context, then attempt to optimistically call the given function directly.
Jonathan Austin 1:8aa5cdb4ab67 267 * We only create an additional fiber if that function performs a block operation.
Jonathan Austin 1:8aa5cdb4ab67 268 *
Jonathan Austin 1:8aa5cdb4ab67 269 * @param entry_fn The function to execute.
Jonathan Austin 1:8aa5cdb4ab67 270 *
Jonathan Austin 1:8aa5cdb4ab67 271 * @param param an untyped parameter passed into the entry_fn and completion_fn.
Jonathan Austin 1:8aa5cdb4ab67 272 *
Jonathan Austin 1:8aa5cdb4ab67 273 * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 274 */
Jonathan Austin 1:8aa5cdb4ab67 275 int invoke(void (*entry_fn)(void *), void *param);
Jonathan Austin 1:8aa5cdb4ab67 276
Jonathan Austin 1:8aa5cdb4ab67 277 /**
Jonathan Austin 1:8aa5cdb4ab67 278 * Resizes the stack allocation of the current fiber if necessary to hold the system stack.
Jonathan Austin 1:8aa5cdb4ab67 279 *
Jonathan Austin 1:8aa5cdb4ab67 280 * If the stack allocation is large enough to hold the current system stack, then this function does nothing.
Jonathan Austin 1:8aa5cdb4ab67 281 * Otherwise, the the current allocation of the fiber is freed, and a larger block is allocated.
Jonathan Austin 1:8aa5cdb4ab67 282 *
Jonathan Austin 1:8aa5cdb4ab67 283 * @param f The fiber context to verify.
Jonathan Austin 1:8aa5cdb4ab67 284 *
Jonathan Austin 1:8aa5cdb4ab67 285 * @return The stack depth of the given fiber.
Jonathan Austin 1:8aa5cdb4ab67 286 */
Jonathan Austin 1:8aa5cdb4ab67 287 inline void verify_stack_size(Fiber *f);
Jonathan Austin 1:8aa5cdb4ab67 288
Jonathan Austin 1:8aa5cdb4ab67 289 /**
Jonathan Austin 1:8aa5cdb4ab67 290 * Event callback. Called from an instance of MicroBitMessageBus whenever an event is raised.
Jonathan Austin 1:8aa5cdb4ab67 291 *
Jonathan Austin 1:8aa5cdb4ab67 292 * This function checks to determine if any fibers blocked on the wait queue need to be woken up
Jonathan Austin 1:8aa5cdb4ab67 293 * and made runnable due to the event.
Jonathan Austin 1:8aa5cdb4ab67 294 *
Jonathan Austin 1:8aa5cdb4ab67 295 * @param evt the event that has just been raised on an instance of MicroBitMessageBus.
Jonathan Austin 1:8aa5cdb4ab67 296 */
Jonathan Austin 1:8aa5cdb4ab67 297 void scheduler_event(MicroBitEvent evt);
Jonathan Austin 1:8aa5cdb4ab67 298
Jonathan Austin 1:8aa5cdb4ab67 299 /**
Jonathan Austin 1:8aa5cdb4ab67 300 * Determines if any fibers are waiting to be scheduled.
Jonathan Austin 1:8aa5cdb4ab67 301 *
Jonathan Austin 1:8aa5cdb4ab67 302 * @return The number of fibers currently on the run queue
Jonathan Austin 1:8aa5cdb4ab67 303 */
Jonathan Austin 1:8aa5cdb4ab67 304 int scheduler_runqueue_empty();
Jonathan Austin 1:8aa5cdb4ab67 305
Jonathan Austin 1:8aa5cdb4ab67 306 /**
Jonathan Austin 1:8aa5cdb4ab67 307 * Utility function to add the currenty running fiber to the given queue.
Jonathan Austin 1:8aa5cdb4ab67 308 *
Jonathan Austin 1:8aa5cdb4ab67 309 * Perform a simple add at the head, to avoid complexity,
Jonathan Austin 1:8aa5cdb4ab67 310 *
Jonathan Austin 1:8aa5cdb4ab67 311 * Queues are normally very short, so maintaining a doubly linked, sorted list typically outweighs the cost of
Jonathan Austin 1:8aa5cdb4ab67 312 * brute force searching.
Jonathan Austin 1:8aa5cdb4ab67 313 *
Jonathan Austin 1:8aa5cdb4ab67 314 * @param f The fiber to add to the queue
Jonathan Austin 1:8aa5cdb4ab67 315 *
Jonathan Austin 1:8aa5cdb4ab67 316 * @param queue The run queue to add the fiber to.
Jonathan Austin 1:8aa5cdb4ab67 317 */
Jonathan Austin 1:8aa5cdb4ab67 318 void queue_fiber(Fiber *f, Fiber **queue);
Jonathan Austin 1:8aa5cdb4ab67 319
Jonathan Austin 1:8aa5cdb4ab67 320 /**
Jonathan Austin 1:8aa5cdb4ab67 321 * Utility function to the given fiber from whichever queue it is currently stored on.
Jonathan Austin 1:8aa5cdb4ab67 322 *
Jonathan Austin 1:8aa5cdb4ab67 323 * @param f the fiber to remove.
Jonathan Austin 1:8aa5cdb4ab67 324 */
Jonathan Austin 1:8aa5cdb4ab67 325 void dequeue_fiber(Fiber *f);
Jonathan Austin 1:8aa5cdb4ab67 326
Jonathan Austin 1:8aa5cdb4ab67 327 /**
Jonathan Austin 1:8aa5cdb4ab67 328 * Set of tasks to perform when idle.
Jonathan Austin 1:8aa5cdb4ab67 329 * Service any background tasks that are required, and attempt a power efficient sleep.
Jonathan Austin 1:8aa5cdb4ab67 330 */
Jonathan Austin 1:8aa5cdb4ab67 331 void idle();
Jonathan Austin 1:8aa5cdb4ab67 332
Jonathan Austin 1:8aa5cdb4ab67 333 /**
Jonathan Austin 1:8aa5cdb4ab67 334 * The idle task, which is called when the runtime has no fibers that require execution.
Jonathan Austin 1:8aa5cdb4ab67 335 *
Jonathan Austin 1:8aa5cdb4ab67 336 * This function typically calls idle().
Jonathan Austin 1:8aa5cdb4ab67 337 */
Jonathan Austin 1:8aa5cdb4ab67 338 void idle_task();
Jonathan Austin 1:8aa5cdb4ab67 339
Jonathan Austin 1:8aa5cdb4ab67 340 /**
Jonathan Austin 1:8aa5cdb4ab67 341 * Adds a component to the array of idle thread components, which are processed
Jonathan Austin 1:8aa5cdb4ab67 342 * when the run queue is empty.
Jonathan Austin 1:8aa5cdb4ab67 343 *
Jonathan Austin 1:8aa5cdb4ab67 344 * The system timer will poll isIdleCallbackNeeded on each component to determine
Jonathan Austin 1:8aa5cdb4ab67 345 * if the scheduler should schedule the idle_task imminently.
Jonathan Austin 1:8aa5cdb4ab67 346 *
Jonathan Austin 1:8aa5cdb4ab67 347 * @param component The component to add to the array.
Jonathan Austin 1:8aa5cdb4ab67 348 *
Jonathan Austin 1:8aa5cdb4ab67 349 * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full.
Jonathan Austin 1:8aa5cdb4ab67 350 *
Jonathan Austin 1:8aa5cdb4ab67 351 * @code
Jonathan Austin 1:8aa5cdb4ab67 352 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
Jonathan Austin 1:8aa5cdb4ab67 353 *
Jonathan Austin 1:8aa5cdb4ab67 354 * // heap allocated - otherwise it will be paged out!
Jonathan Austin 1:8aa5cdb4ab67 355 * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c);
Jonathan Austin 1:8aa5cdb4ab67 356 *
Jonathan Austin 1:8aa5cdb4ab67 357 * fiber_add_idle_component(accelerometer);
Jonathan Austin 1:8aa5cdb4ab67 358 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 359 */
Jonathan Austin 1:8aa5cdb4ab67 360 int fiber_add_idle_component(MicroBitComponent *component);
Jonathan Austin 1:8aa5cdb4ab67 361
Jonathan Austin 1:8aa5cdb4ab67 362 /**
Jonathan Austin 1:8aa5cdb4ab67 363 * Remove a component from the array of idle thread components
Jonathan Austin 1:8aa5cdb4ab67 364 *
Jonathan Austin 1:8aa5cdb4ab67 365 * @param component The component to remove from the idle component array.
Jonathan Austin 1:8aa5cdb4ab67 366 *
Jonathan Austin 1:8aa5cdb4ab67 367 * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
Jonathan Austin 1:8aa5cdb4ab67 368 *
Jonathan Austin 1:8aa5cdb4ab67 369 * @code
Jonathan Austin 1:8aa5cdb4ab67 370 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
Jonathan Austin 1:8aa5cdb4ab67 371 *
Jonathan Austin 1:8aa5cdb4ab67 372 * // heap allocated - otherwise it will be paged out!
Jonathan Austin 1:8aa5cdb4ab67 373 * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c);
Jonathan Austin 1:8aa5cdb4ab67 374 *
Jonathan Austin 1:8aa5cdb4ab67 375 * fiber_add_idle_component(accelerometer);
Jonathan Austin 1:8aa5cdb4ab67 376 *
Jonathan Austin 1:8aa5cdb4ab67 377 * fiber_remove_idle_component(accelerometer);
Jonathan Austin 1:8aa5cdb4ab67 378 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 379 */
Jonathan Austin 1:8aa5cdb4ab67 380 int fiber_remove_idle_component(MicroBitComponent *component);
Jonathan Austin 1:8aa5cdb4ab67 381
Jonathan Austin 1:8aa5cdb4ab67 382 /**
Jonathan Austin 1:8aa5cdb4ab67 383 * Determines if the processor is executing in interrupt context.
Jonathan Austin 1:8aa5cdb4ab67 384 *
Jonathan Austin 1:8aa5cdb4ab67 385 * @return true if any the processor is currently executing any interrupt service routine. False otherwise.
Jonathan Austin 1:8aa5cdb4ab67 386 */
Jonathan Austin 1:8aa5cdb4ab67 387 inline int inInterruptContext()
Jonathan Austin 1:8aa5cdb4ab67 388 {
Jonathan Austin 1:8aa5cdb4ab67 389 return (((int)__get_IPSR()) & 0x003F) > 0;
Jonathan Austin 1:8aa5cdb4ab67 390 }
Jonathan Austin 1:8aa5cdb4ab67 391
Jonathan Austin 1:8aa5cdb4ab67 392 /**
Jonathan Austin 1:8aa5cdb4ab67 393 * Assembler Context switch routing.
Jonathan Austin 1:8aa5cdb4ab67 394 * Defined in CortexContextSwitch.s.
Jonathan Austin 1:8aa5cdb4ab67 395 */
Jonathan Austin 1:8aa5cdb4ab67 396 extern "C" void swap_context(Cortex_M0_TCB *from, Cortex_M0_TCB *to, uint32_t from_stack, uint32_t to_stack);
Jonathan Austin 1:8aa5cdb4ab67 397 extern "C" void save_context(Cortex_M0_TCB *tcb, uint32_t stack);
Jonathan Austin 1:8aa5cdb4ab67 398 extern "C" void save_register_context(Cortex_M0_TCB *tcb);
Jonathan Austin 1:8aa5cdb4ab67 399 extern "C" void restore_register_context(Cortex_M0_TCB *tcb);
Jonathan Austin 1:8aa5cdb4ab67 400
Jonathan Austin 1:8aa5cdb4ab67 401 #endif