Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Committer:
AndrewL
Date:
Mon Jan 09 03:11:46 2012 +0000
Revision:
6:cf660b28b2a4
Parent:
4:e740e08cbea9
Fixed error relating to timer events posted to tasks that are not waiting

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AndrewL 0:1dafafe7d505 1 /***********************************************************************************
AndrewL 0:1dafafe7d505 2 * m b o s R T O S F O R m b e d (ARM CORTEX M3)
AndrewL 0:1dafafe7d505 3 *
AndrewL 0:1dafafe7d505 4 * Copyright (c) 2010 - 2011 Andrew Levido
AndrewL 0:1dafafe7d505 5 *
AndrewL 0:1dafafe7d505 6 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
AndrewL 0:1dafafe7d505 7 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
AndrewL 0:1dafafe7d505 8 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
AndrewL 0:1dafafe7d505 9 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
AndrewL 0:1dafafe7d505 10 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
AndrewL 0:1dafafe7d505 11 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
AndrewL 0:1dafafe7d505 12 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
AndrewL 0:1dafafe7d505 13 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
AndrewL 0:1dafafe7d505 14 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
AndrewL 0:1dafafe7d505 15 */
AndrewL 0:1dafafe7d505 16 #ifndef MBOS_H
AndrewL 0:1dafafe7d505 17 #define MBOS_H
AndrewL 0:1dafafe7d505 18
AndrewL 0:1dafafe7d505 19 typedef unsigned int uint;
AndrewL 0:1dafafe7d505 20
AndrewL 0:1dafafe7d505 21 /**A pre-emptive, mutlitasking real-time operating system for mbed applications.
AndrewL 0:1dafafe7d505 22 *
AndrewL 0:1dafafe7d505 23 * Allows the user to write their application in the form of independant tasks.
AndrewL 0:1dafafe7d505 24 * The operating system manages a completely separate processor context for each
AndrewL 0:1dafafe7d505 25 * task (processor registers and stack) and swaps between the tasks according to a
AndrewL 0:1dafafe7d505 26 * simple scheduling algorithm.
AndrewL 0:1dafafe7d505 27 *
AndrewL 0:1dafafe7d505 28 * Tasks are allocated a priority, and the scheduler ensures that the task
AndrewL 0:1dafafe7d505 29 * that with the highest priority that is not waiting for an event, has control of
AndrewL 0:1dafafe7d505 30 * the processor. If more than one task shares the highest priority, they will be
AndrewL 0:1dafafe7d505 31 * run sequentially in round-robin fashion.
AndrewL 0:1dafafe7d505 32 *
AndrewL 0:1dafafe7d505 33 * Each task may wait for one or more of up to 32 different events, each represented by
AndrewL 0:1dafafe7d505 34 * one bit in the event flags word. Events may be posted by another task, by a mbos
AndrewL 0:1dafafe7d505 35 * timer, or in response to some asynchronous event such as an peripheral interrupt.
AndrewL 0:1dafafe7d505 36 *
AndrewL 0:1dafafe7d505 37 * mbos implements the SysTick timer to generate a System Tick every millisecond.
AndrewL 0:1dafafe7d505 38 * Scheduling occurs once every Tick, or whenever a task blocks or an event is posted.
AndrewL 0:1dafafe7d505 39 * The user may create one-shot or continuous timers to post events to tasks.
AndrewL 0:1dafafe7d505 40 *
AndrewL 0:1dafafe7d505 41 * mbos implements a simple ceiling protocol resource locking mechanism To manage access
AndrewL 0:1dafafe7d505 42 * to system resources. Tasks may take exclusive ownership of resources for a period.
AndrewL 0:1dafafe7d505 43 *
AndrewL 0:1dafafe7d505 44 * A typical simple example with two tasks, and one timer, might look like this:
AndrewL 0:1dafafe7d505 45 * @code
AndrewL 4:e740e08cbea9 46 * // mbos Blinky demonstration.
AndrewL 4:e740e08cbea9 47 * // Task 1 toggles LED1 every second, under control of a timer. It then posts an event to
AndrewL 4:e740e08cbea9 48 * // task 2 which flashed LED2 briefly.
AndrewL 4:e740e08cbea9 49 * #include "mbed.h"
AndrewL 0:1dafafe7d505 50 * #include "mbos.h"
AndrewL 0:1dafafe7d505 51 *
AndrewL 4:e740e08cbea9 52 * #define TASK1_ID 1 // Id for task 1 (idle task is 0)
AndrewL 4:e740e08cbea9 53 * #define TASK1_PRIO 50 // priority for task 1
AndrewL 4:e740e08cbea9 54 * #define TASK1_STACK_SZ 32 // stack size for task 1 in words
AndrewL 4:e740e08cbea9 55 * #define TASK2_ID 2 // Id for task 2
AndrewL 4:e740e08cbea9 56 * #define TASK2_PRIO 60 // priority for task 2
AndrewL 4:e740e08cbea9 57 * #define TASK2_STACK_SZ 32 // stack size for task 2 in words
AndrewL 4:e740e08cbea9 58 * #define TIMER0_ID 0 // Id for timer 0
AndrewL 4:e740e08cbea9 59 * #define TIMER0_PERIOD 1000 // Time period in milliseconds
AndrewL 4:e740e08cbea9 60 * #define TIMER0_EVENT 1 // Event flag (1 << 0)
AndrewL 4:e740e08cbea9 61 * #define T1_TO_T2_EVENT 2 // Event flag (1 << 1)
AndrewL 0:1dafafe7d505 62 *
AndrewL 4:e740e08cbea9 63 * void task1(void); // task function prototypes
AndrewL 0:1dafafe7d505 64 * void task2(void);
AndrewL 0:1dafafe7d505 65 *
AndrewL 0:1dafafe7d505 66 * DigitalOut led1(LED1);
AndrewL 0:1dafafe7d505 67 * DigitalOut led2(LED2);
AndrewL 4:e740e08cbea9 68 * mbos os(2, 1); // Instantiate mbos with 2 tasks & 1 timer
AndrewL 0:1dafafe7d505 69 *
AndrewL 0:1dafafe7d505 70 * int main(void)
AndrewL 0:1dafafe7d505 71 * {
AndrewL 4:e740e08cbea9 72 * // Configure tasks and timers
AndrewL 0:1dafafe7d505 73 * os.CreateTask(TASK1_ID, TASK1_PRIO, TASK1_STACK_SZ, task1);
AndrewL 0:1dafafe7d505 74 * os.CreateTask(TASK2_ID, TASK2_PRIO, TASK2_STACK_SZ, task2);
AndrewL 0:1dafafe7d505 75 * os.CreateTimer(TIMER0_ID, TIMER0_EVENT, TASK1_ID);
AndrewL 4:e740e08cbea9 76 * // Start mbos
AndrewL 0:1dafafe7d505 77 * os.Start();
AndrewL 4:e740e08cbea9 78 * // never return!
AndrewL 0:1dafafe7d505 79 * }
AndrewL 4:e740e08cbea9 80 *
AndrewL 0:1dafafe7d505 81 * void task1(void)
AndrewL 0:1dafafe7d505 82 * {
AndrewL 0:1dafafe7d505 83 * os.SetTimer(TIMER0_ID, TIMER0_PERIOD, TIMER0_PERIOD);
AndrewL 0:1dafafe7d505 84 * while(1){
AndrewL 4:e740e08cbea9 85 * os.WaitEvent(TIMER0_EVENT);
AndrewL 4:e740e08cbea9 86 * led1 = !led1;
AndrewL 4:e740e08cbea9 87 * os.SetEvent(T1_TO_T2_EVENT, TASK2_ID);
AndrewL 4:e740e08cbea9 88 * }
AndrewL 0:1dafafe7d505 89 * }
AndrewL 4:e740e08cbea9 90 *
AndrewL 0:1dafafe7d505 91 * void task2(void)
AndrewL 0:1dafafe7d505 92 * {
AndrewL 4:e740e08cbea9 93 * while(1){
AndrewL 4:e740e08cbea9 94 * os.WaitEvent(T1_TO_T2_EVENT);
AndrewL 4:e740e08cbea9 95 * led2 = 1;
AndrewL 4:e740e08cbea9 96 * wait_ms(100);
AndrewL 4:e740e08cbea9 97 * led2 = 0;
AndrewL 4:e740e08cbea9 98 * }
AndrewL 0:1dafafe7d505 99 * }
AndrewL 0:1dafafe7d505 100 * @endcode
AndrewL 0:1dafafe7d505 101 */
AndrewL 0:1dafafe7d505 102
AndrewL 0:1dafafe7d505 103 class mbos {
AndrewL 0:1dafafe7d505 104 public:
AndrewL 2:af930cdf7cce 105 /** Create an mbos object. Instantiate mbos and define the number of tasks, timers
AndrewL 2:af930cdf7cce 106 * and resources.
AndrewL 0:1dafafe7d505 107 *
AndrewL 2:af930cdf7cce 108 * @param ntasks The number of user tasks (1 .. 99).
AndrewL 2:af930cdf7cce 109 * @param ntimers Optional number of timers (0 .. 100).
AndrewL 2:af930cdf7cce 110 * @param nresources Optional number of resources (0 .. 100).
AndrewL 0:1dafafe7d505 111 */
AndrewL 0:1dafafe7d505 112 mbos(uint ntasks, uint ntimers = 0, uint nresources = 0);
AndrewL 0:1dafafe7d505 113
AndrewL 2:af930cdf7cce 114 /** Start mbos. Optionally specify the size of the stack for a user-written idle task.
AndrewL 2:af930cdf7cce 115 * All tasks, timers and resources must be created before calling Start.
AndrewL 0:1dafafe7d505 116 *
AndrewL 2:af930cdf7cce 117 * @param idlestacksize Size in words (>= 32) of the user-written idle task if present.
AndrewL 0:1dafafe7d505 118 * @returns Never returns
AndrewL 0:1dafafe7d505 119 */
AndrewL 4:e740e08cbea9 120 void Start(uint idlestacksize = 32);
AndrewL 0:1dafafe7d505 121
AndrewL 2:af930cdf7cce 122 /** Create an mbos task. Allocates and initialises data structures for the task.
AndrewL 0:1dafafe7d505 123 *
AndrewL 2:af930cdf7cce 124 * @param taskid Unique ID for the task. (1 .. ntasks).
AndrewL 0:1dafafe7d505 125 * @param priority Priority (0 .. 99) of the task. Tasks may share the same priority.
AndrewL 2:af930cdf7cce 126 * @param stacksize Size in words (>= 32) of the task's stack.
AndrewL 2:af930cdf7cce 127 * @param fun Pointer to the task function. Function must be of type static void,
AndrewL 2:af930cdf7cce 128 * and must return nothing.
AndrewL 0:1dafafe7d505 129 */
AndrewL 0:1dafafe7d505 130 void CreateTask(uint taskid, uint priority, uint stacksz, void (*fun)(void));
AndrewL 0:1dafafe7d505 131
AndrewL 2:af930cdf7cce 132 /** Get the ID of the current task.
AndrewL 0:1dafafe7d505 133 *
AndrewL 2:af930cdf7cce 134 * @returns The ID (0 .. 99) of the calling task.
AndrewL 0:1dafafe7d505 135 */
AndrewL 0:1dafafe7d505 136 uint GetTask(void);
AndrewL 0:1dafafe7d505 137
AndrewL 2:af930cdf7cce 138 /** Set the priority of the current task. Does nothing if called from the idle task.
AndrewL 0:1dafafe7d505 139 *
AndrewL 0:1dafafe7d505 140 * @param priority Priority (0 .. 99) to apply to the calling task.
AndrewL 0:1dafafe7d505 141 */
AndrewL 0:1dafafe7d505 142 void SetPriority(uint priority);
AndrewL 0:1dafafe7d505 143
AndrewL 1:b453bba9c5c0 144 /** Get the priority of the current task.
AndrewL 0:1dafafe7d505 145 *
AndrewL 2:af930cdf7cce 146 * @returns The priority (0 .. 99) of the calling task.
AndrewL 0:1dafafe7d505 147 */
AndrewL 0:1dafafe7d505 148 uint GetPriority(void);
AndrewL 0:1dafafe7d505 149
AndrewL 2:af930cdf7cce 150 /** Wait for an event or events. Causes the current task to block, waiting for the
AndrewL 2:af930cdf7cce 151 * specified event. Does nothing if called from the idle task, or if the event is NULL.
AndrewL 0:1dafafe7d505 152 *
AndrewL 1:b453bba9c5c0 153 * @param event Event flag(s) to wait for.
AndrewL 0:1dafafe7d505 154 */
AndrewL 0:1dafafe7d505 155 void WaitEvent(uint event);
AndrewL 0:1dafafe7d505 156
AndrewL 3:6cb5413f143f 157 /** Post an event or events to a task.
AndrewL 2:af930cdf7cce 158 * Posts the nominated event(s) to the specified task. Forces a context switch if the events
AndrewL 2:af930cdf7cce 159 * are posted successfully. Does nothing if the task is not waiting, or is not waiting for
AndrewL 2:af930cdf7cce 160 * the posted event.
AndrewL 0:1dafafe7d505 161 *
AndrewL 0:1dafafe7d505 162 * @param event Event flag(s) to post.
AndrewL 0:1dafafe7d505 163 * @param task The ID of the task to which to post the event(s). May not be idle task.
AndrewL 0:1dafafe7d505 164 */
AndrewL 0:1dafafe7d505 165 void SetEvent(uint event, uint task);
AndrewL 0:1dafafe7d505 166
AndrewL 2:af930cdf7cce 167 /** Returns the event flag(s) which last caused the task to unblock.
AndrewL 0:1dafafe7d505 168 *
AndrewL 0:1dafafe7d505 169 * @returns The event flags.
AndrewL 0:1dafafe7d505 170 */
AndrewL 0:1dafafe7d505 171 uint GetEvent(void);
AndrewL 0:1dafafe7d505 172
AndrewL 2:af930cdf7cce 173 /** Create a mbos timer. Allocates and initialises the data structures for the timer.
AndrewL 0:1dafafe7d505 174 *
AndrewL 2:af930cdf7cce 175 * @param timerid Unique ID for the timer (0 .. ntimers - 1).
AndrewL 2:af930cdf7cce 176 * @param taskid The ID of the task to which the timer will post events. May not be
AndrewL 2:af930cdf7cce 177 * the idle task.
AndrewL 0:1dafafe7d505 178 * @param event The event flag(s) that the timer should post on timeout. May not be NULL.
AndrewL 0:1dafafe7d505 179 */
AndrewL 0:1dafafe7d505 180 void CreateTimer(uint timerid, uint taskid, uint event);
AndrewL 0:1dafafe7d505 181
AndrewL 2:af930cdf7cce 182 /** Starts an mbos timer. If the reload time is zero or omitted, the timer will be reset
AndrewL 2:af930cdf7cce 183 * once it has posted a single event, after time milliseconds. If the reload time is
AndrewL 2:af930cdf7cce 184 * non-zero, this value will be loaded into the timer on time-out, and the timer will
AndrewL 2:af930cdf7cce 185 * continue indefinitely. In this case the interval to the first event will be time,
AndrewL 2:af930cdf7cce 186 * and the interval between subsequent events will be reloadtime.
AndrewL 0:1dafafe7d505 187 *
AndrewL 2:af930cdf7cce 188 * @param timerid The ID of the timer.
AndrewL 0:1dafafe7d505 189 * @param time The period in milliseconds before the timer times out.
AndrewL 0:1dafafe7d505 190 * @param reload The optional time to reload into the timer when it times out.
AndrewL 0:1dafafe7d505 191 */
AndrewL 0:1dafafe7d505 192 void SetTimer(uint timerid, uint time, uint reload = 0);
AndrewL 4:e740e08cbea9 193
AndrewL 4:e740e08cbea9 194 /** Redirects an mbos timer. Changes the task and event associated with a timer. If the timer
AndrewL 4:e740e08cbea9 195 * is running, the fun ction has no effect.
AndrewL 4:e740e08cbea9 196 *
AndrewL 4:e740e08cbea9 197 * @param timerid The ID of the timer.
AndrewL 4:e740e08cbea9 198 * @param taskid The ID of the task to which the timer will post events. May not be
AndrewL 4:e740e08cbea9 199 * the idle task.
AndrewL 4:e740e08cbea9 200 * @param event The event flag(s) that the timer should post on timeout. May not be NULL.
AndrewL 4:e740e08cbea9 201 */
AndrewL 4:e740e08cbea9 202 void RedirectTimer(uint timerid, uint taskid, uint event);
AndrewL 0:1dafafe7d505 203
AndrewL 2:af930cdf7cce 204 /** Stops and clears an mbos timer.
AndrewL 0:1dafafe7d505 205 *
AndrewL 2:af930cdf7cce 206 * @param timerid The ID of the timer to clear.
AndrewL 0:1dafafe7d505 207 */
AndrewL 0:1dafafe7d505 208 void ClearTimer(uint timerid);
AndrewL 0:1dafafe7d505 209
AndrewL 2:af930cdf7cce 210 /** Creates an mbos resource. Allocates and initialises the data structures for the Resource.
AndrewL 0:1dafafe7d505 211 *
AndrewL 2:af930cdf7cce 212 * @param resourceid Unique ID for the resource (0 .. nresource).
AndrewL 2:af930cdf7cce 213 * @param priority Priority of the resource (normally > than that of any task using the
AndrewL 2:af930cdf7cce 214 * resource).
AndrewL 0:1dafafe7d505 215 */
AndrewL 0:1dafafe7d505 216 void CreateResource(uint resourceid, uint priority);
AndrewL 0:1dafafe7d505 217
AndrewL 2:af930cdf7cce 218 /** Locks an mbos resource and temporarily allocates the resource's priority to the calling
AndrewL 2:af930cdf7cce 219 * task.
AndrewL 2:af930cdf7cce 220 * Does nothing if the resource is already locked, or if called from the idle task.
AndrewL 0:1dafafe7d505 221 *
AndrewL 2:af930cdf7cce 222 * @param resourceid The ID of the resource to lock.
AndrewL 2:af930cdf7cce 223 * @returns Zero if the resource was locked successfully, or the ID of the task that is
AndrewL 2:af930cdf7cce 224 * currently locking the resource, if not.
AndrewL 0:1dafafe7d505 225 */
AndrewL 0:1dafafe7d505 226 uint LockResource(uint resourceid);
AndrewL 0:1dafafe7d505 227
AndrewL 2:af930cdf7cce 228 /** Tests whether a resource is locked or free, without changing its state.
AndrewL 0:1dafafe7d505 229 *
AndrewL 2:af930cdf7cce 230 * @param resourceid The ID of the resouce to test.
AndrewL 2:af930cdf7cce 231 * @returns Zero if the resource is free, or the ID of the task that is currently
AndrewL 2:af930cdf7cce 232 * locking the resouce , if not.
AndrewL 0:1dafafe7d505 233
AndrewL 0:1dafafe7d505 234 */
AndrewL 0:1dafafe7d505 235 uint TestResource(uint resourceid);
AndrewL 0:1dafafe7d505 236
AndrewL 0:1dafafe7d505 237 /** Frees a resource
AndrewL 2:af930cdf7cce 238 * Frees an mbos resource and restores the calling task's original priority. Does nothing
AndrewL 2:af930cdf7cce 239 * if the resource is already free, if called from the idle task, or the resource was
AndrewL 2:af930cdf7cce 240 * locked by a different task.
AndrewL 0:1dafafe7d505 241 *
AndrewL 2:af930cdf7cce 242 * @param resourceid The ID of the resource t free.
AndrewL 2:af930cdf7cce 243 * @returns Zero if the resource was freed successfully, or the ID of the task that is
AndrewL 2:af930cdf7cce 244 * locking the resource, if not.
AndrewL 0:1dafafe7d505 245 */
AndrewL 0:1dafafe7d505 246 uint FreeResource(uint resource);
AndrewL 0:1dafafe7d505 247
AndrewL 0:1dafafe7d505 248 private:
AndrewL 0:1dafafe7d505 249 uint* _initstack(uint *stack, void (*fun)());
AndrewL 0:1dafafe7d505 250 };
AndrewL 0:1dafafe7d505 251 #endif