Revised to disable BLE for radio communication as needed.

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit

Committer:
tsfarber
Date:
Tue Nov 26 04:12:46 2019 +0000
Revision:
74:26717338739d
Parent:
41:da05ec75cd5d
This program combines samples programs radio TX and radio RX so that both units can send or receive depending on which unit's buttons are pressed. Tested successfully. MicroBitConfig.h has been edited to disable BLE.

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 * @param component The component to add to the array.
Jonathan Austin 1:8aa5cdb4ab67 345 * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full.
Jonathan Austin 1:8aa5cdb4ab67 346 */
Jonathan Austin 1:8aa5cdb4ab67 347 int fiber_add_idle_component(MicroBitComponent *component);
Jonathan Austin 1:8aa5cdb4ab67 348
Jonathan Austin 1:8aa5cdb4ab67 349 /**
LancasterUniversity 41:da05ec75cd5d 350 * remove a component from the array of idle thread components
Jonathan Austin 1:8aa5cdb4ab67 351 *
LancasterUniversity 41:da05ec75cd5d 352 * @param component the component to remove from the idle component array.
LancasterUniversity 41:da05ec75cd5d 353 * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
Jonathan Austin 1:8aa5cdb4ab67 354 */
Jonathan Austin 1:8aa5cdb4ab67 355 int fiber_remove_idle_component(MicroBitComponent *component);
Jonathan Austin 1:8aa5cdb4ab67 356
Jonathan Austin 1:8aa5cdb4ab67 357 /**
Jonathan Austin 1:8aa5cdb4ab67 358 * Determines if the processor is executing in interrupt context.
Jonathan Austin 1:8aa5cdb4ab67 359 *
Jonathan Austin 1:8aa5cdb4ab67 360 * @return true if any the processor is currently executing any interrupt service routine. False otherwise.
Jonathan Austin 1:8aa5cdb4ab67 361 */
Jonathan Austin 1:8aa5cdb4ab67 362 inline int inInterruptContext()
Jonathan Austin 1:8aa5cdb4ab67 363 {
Jonathan Austin 1:8aa5cdb4ab67 364 return (((int)__get_IPSR()) & 0x003F) > 0;
Jonathan Austin 1:8aa5cdb4ab67 365 }
Jonathan Austin 1:8aa5cdb4ab67 366
Jonathan Austin 1:8aa5cdb4ab67 367 /**
Jonathan Austin 1:8aa5cdb4ab67 368 * Assembler Context switch routing.
Jonathan Austin 1:8aa5cdb4ab67 369 * Defined in CortexContextSwitch.s.
Jonathan Austin 1:8aa5cdb4ab67 370 */
Jonathan Austin 1:8aa5cdb4ab67 371 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 372 extern "C" void save_context(Cortex_M0_TCB *tcb, uint32_t stack);
Jonathan Austin 1:8aa5cdb4ab67 373 extern "C" void save_register_context(Cortex_M0_TCB *tcb);
Jonathan Austin 1:8aa5cdb4ab67 374 extern "C" void restore_register_context(Cortex_M0_TCB *tcb);
Jonathan Austin 1:8aa5cdb4ab67 375
LancasterUniversity 41:da05ec75cd5d 376 #endif