Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Committer:
AndrewL
Date:
Sun Dec 05 13:21:15 2010 +0000
Revision:
2:af930cdf7cce
Parent:
1:b453bba9c5c0
Child:
3:6cb5413f143f
v1.0c

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 0:1dafafe7d505 46 * #include "mbed.h"
AndrewL 0:1dafafe7d505 47 * #include "mbos.h"
AndrewL 0:1dafafe7d505 48 *
AndrewL 1:b453bba9c5c0 49 * #define TASK1_ID 1 // defines to make the code more readable
AndrewL 1:b453bba9c5c0 50 * #define TASK1_PRIO 50
AndrewL 1:b453bba9c5c0 51 * #define TASK1_STACK_SZ 32
AndrewL 1:b453bba9c5c0 52 * #define TASK2_ID 2
AndrewL 1:b453bba9c5c0 53 * #define TASK2_PRIO 60
AndrewL 1:b453bba9c5c0 54 * #define TASK2_STACK_SZ 32
AndrewL 1:b453bba9c5c0 55 * #define TIMER0_ID 0
AndrewL 1:b453bba9c5c0 56 * #define TIMER0_PERIOD 1000
AndrewL 1:b453bba9c5c0 57 * #define TIMER0_EVENT 1
AndrewL 1:b453bba9c5c0 58 * #define T1_TO_T2_EVENT 2
AndrewL 0:1dafafe7d505 59 *
AndrewL 1:b453bba9c5c0 60 * void task1(void); // task function prototypes
AndrewL 0:1dafafe7d505 61 * void task2(void);
AndrewL 0:1dafafe7d505 62 *
AndrewL 0:1dafafe7d505 63 * DigitalOut led1(LED1);
AndrewL 0:1dafafe7d505 64 * DigitalOut led2(LED2);
AndrewL 1:b453bba9c5c0 65 * mbos os(2, 1); // 2 tasks, 1 timer
AndrewL 0:1dafafe7d505 66 *
AndrewL 0:1dafafe7d505 67 * int main(void)
AndrewL 0:1dafafe7d505 68 * {
AndrewL 0:1dafafe7d505 69 * os.CreateTask(TASK1_ID, TASK1_PRIO, TASK1_STACK_SZ, task1);
AndrewL 0:1dafafe7d505 70 * os.CreateTask(TASK2_ID, TASK2_PRIO, TASK2_STACK_SZ, task2);
AndrewL 0:1dafafe7d505 71 * os.CreateTimer(TIMER0_ID, TIMER0_EVENT, TASK1_ID);
AndrewL 0:1dafafe7d505 72 * os.Start();
AndrewL 0:1dafafe7d505 73 * // never get here!
AndrewL 0:1dafafe7d505 74 * }
AndrewL 0:1dafafe7d505 75 * void task1(void)
AndrewL 0:1dafafe7d505 76 * {
AndrewL 0:1dafafe7d505 77 * os.SetTimer(TIMER0_ID, TIMER0_PERIOD, TIMER0_PERIOD);
AndrewL 0:1dafafe7d505 78 * while(1){
AndrewL 1:b453bba9c5c0 79 * os.WaitEvent(TIMER0_EVENT);
AndrewL 1:b453bba9c5c0 80 * led1 = !led1;
AndrewL 1:b453bba9c5c0 81 * os.SetEvent(T1_TO_T2_EVENT, TASK2_ID);
AndrewL 1:b453bba9c5c0 82 * }
AndrewL 0:1dafafe7d505 83 * }
AndrewL 0:1dafafe7d505 84 * void task2(void)
AndrewL 0:1dafafe7d505 85 * {
AndrewL 1:b453bba9c5c0 86 * while(1){
AndrewL 1:b453bba9c5c0 87 * os.WaitEvent(T1_TO_T2_EVENT);
AndrewL 1:b453bba9c5c0 88 * led2 = 1;
AndrewL 1:b453bba9c5c0 89 * wait_ms(100);
AndrewL 1:b453bba9c5c0 90 * led2 = 0;
AndrewL 1:b453bba9c5c0 91 * }
AndrewL 0:1dafafe7d505 92 * }
AndrewL 0:1dafafe7d505 93 * @endcode
AndrewL 0:1dafafe7d505 94 */
AndrewL 0:1dafafe7d505 95
AndrewL 0:1dafafe7d505 96 class mbos {
AndrewL 0:1dafafe7d505 97 public:
AndrewL 2:af930cdf7cce 98 /** Create an mbos object. Instantiate mbos and define the number of tasks, timers
AndrewL 2:af930cdf7cce 99 * and resources.
AndrewL 0:1dafafe7d505 100 *
AndrewL 2:af930cdf7cce 101 * @param ntasks The number of user tasks (1 .. 99).
AndrewL 2:af930cdf7cce 102 * @param ntimers Optional number of timers (0 .. 100).
AndrewL 2:af930cdf7cce 103 * @param nresources Optional number of resources (0 .. 100).
AndrewL 0:1dafafe7d505 104 */
AndrewL 0:1dafafe7d505 105 mbos(uint ntasks, uint ntimers = 0, uint nresources = 0);
AndrewL 0:1dafafe7d505 106
AndrewL 2:af930cdf7cce 107 /** Start mbos. Optionally specify the size of the stack for a user-written idle task.
AndrewL 2:af930cdf7cce 108 * All tasks, timers and resources must be created before calling Start.
AndrewL 0:1dafafe7d505 109 *
AndrewL 2:af930cdf7cce 110 * @param idlestacksize Size in words (>= 32) of the user-written idle task if present.
AndrewL 0:1dafafe7d505 111 * @returns Never returns
AndrewL 0:1dafafe7d505 112 */
AndrewL 0:1dafafe7d505 113 void Start(uint idlestacksize = 0);
AndrewL 0:1dafafe7d505 114
AndrewL 2:af930cdf7cce 115 /** Create an mbos task. Allocates and initialises data structures for the task.
AndrewL 0:1dafafe7d505 116 *
AndrewL 2:af930cdf7cce 117 * @param taskid Unique ID for the task. (1 .. ntasks).
AndrewL 0:1dafafe7d505 118 * @param priority Priority (0 .. 99) of the task. Tasks may share the same priority.
AndrewL 2:af930cdf7cce 119 * @param stacksize Size in words (>= 32) of the task's stack.
AndrewL 2:af930cdf7cce 120 * @param fun Pointer to the task function. Function must be of type static void,
AndrewL 2:af930cdf7cce 121 * and must return nothing.
AndrewL 0:1dafafe7d505 122 */
AndrewL 0:1dafafe7d505 123 void CreateTask(uint taskid, uint priority, uint stacksz, void (*fun)(void));
AndrewL 0:1dafafe7d505 124
AndrewL 2:af930cdf7cce 125 /** Get the ID of the current task.
AndrewL 0:1dafafe7d505 126 *
AndrewL 2:af930cdf7cce 127 * @returns The ID (0 .. 99) of the calling task.
AndrewL 0:1dafafe7d505 128 */
AndrewL 0:1dafafe7d505 129 uint GetTask(void);
AndrewL 0:1dafafe7d505 130
AndrewL 2:af930cdf7cce 131 /** Set the priority of the current task. Does nothing if called from the idle task.
AndrewL 0:1dafafe7d505 132 *
AndrewL 0:1dafafe7d505 133 * @param priority Priority (0 .. 99) to apply to the calling task.
AndrewL 0:1dafafe7d505 134 */
AndrewL 0:1dafafe7d505 135 void SetPriority(uint priority);
AndrewL 0:1dafafe7d505 136
AndrewL 1:b453bba9c5c0 137 /** Get the priority of the current task.
AndrewL 0:1dafafe7d505 138 *
AndrewL 2:af930cdf7cce 139 * @returns The priority (0 .. 99) of the calling task.
AndrewL 0:1dafafe7d505 140 */
AndrewL 0:1dafafe7d505 141 uint GetPriority(void);
AndrewL 0:1dafafe7d505 142
AndrewL 2:af930cdf7cce 143 /** Wait for an event or events. Causes the current task to block, waiting for the
AndrewL 2:af930cdf7cce 144 * specified event. Does nothing if called from the idle task, or if the event is NULL.
AndrewL 0:1dafafe7d505 145 *
AndrewL 1:b453bba9c5c0 146 * @param event Event flag(s) to wait for.
AndrewL 0:1dafafe7d505 147 */
AndrewL 0:1dafafe7d505 148 void WaitEvent(uint event);
AndrewL 0:1dafafe7d505 149
AndrewL 0:1dafafe7d505 150 /** Post an event or events to a soecified task.
AndrewL 2:af930cdf7cce 151 * Posts the nominated event(s) to the specified task. Forces a context switch if the events
AndrewL 2:af930cdf7cce 152 * are posted successfully. Does nothing if the task is not waiting, or is not waiting for
AndrewL 2:af930cdf7cce 153 * the posted event.
AndrewL 0:1dafafe7d505 154 *
AndrewL 0:1dafafe7d505 155 * @param event Event flag(s) to post.
AndrewL 0:1dafafe7d505 156 * @param task The ID of the task to which to post the event(s). May not be idle task.
AndrewL 0:1dafafe7d505 157 */
AndrewL 0:1dafafe7d505 158 void SetEvent(uint event, uint task);
AndrewL 0:1dafafe7d505 159
AndrewL 2:af930cdf7cce 160 /** Returns the event flag(s) which last caused the task to unblock.
AndrewL 0:1dafafe7d505 161 *
AndrewL 0:1dafafe7d505 162 * @returns The event flags.
AndrewL 0:1dafafe7d505 163 */
AndrewL 0:1dafafe7d505 164 uint GetEvent(void);
AndrewL 0:1dafafe7d505 165
AndrewL 2:af930cdf7cce 166 /** Create a mbos timer. Allocates and initialises the data structures for the timer.
AndrewL 0:1dafafe7d505 167 *
AndrewL 2:af930cdf7cce 168 * @param timerid Unique ID for the timer (0 .. ntimers - 1).
AndrewL 2:af930cdf7cce 169 * @param taskid The ID of the task to which the timer will post events. May not be
AndrewL 2:af930cdf7cce 170 * the idle task.
AndrewL 0:1dafafe7d505 171 * @param event The event flag(s) that the timer should post on timeout. May not be NULL.
AndrewL 0:1dafafe7d505 172 */
AndrewL 0:1dafafe7d505 173 void CreateTimer(uint timerid, uint taskid, uint event);
AndrewL 0:1dafafe7d505 174
AndrewL 2:af930cdf7cce 175 /** Starts an mbos timer. If the reload time is zero or omitted, the timer will be reset
AndrewL 2:af930cdf7cce 176 * once it has posted a single event, after time milliseconds. If the reload time is
AndrewL 2:af930cdf7cce 177 * non-zero, this value will be loaded into the timer on time-out, and the timer will
AndrewL 2:af930cdf7cce 178 * continue indefinitely. In this case the interval to the first event will be time,
AndrewL 2:af930cdf7cce 179 * and the interval between subsequent events will be reloadtime.
AndrewL 0:1dafafe7d505 180 *
AndrewL 2:af930cdf7cce 181 * @param timerid The ID of the timer.
AndrewL 0:1dafafe7d505 182 * @param time The period in milliseconds before the timer times out.
AndrewL 0:1dafafe7d505 183 * @param reload The optional time to reload into the timer when it times out.
AndrewL 0:1dafafe7d505 184 */
AndrewL 0:1dafafe7d505 185 void SetTimer(uint timerid, uint time, uint reload = 0);
AndrewL 0:1dafafe7d505 186
AndrewL 2:af930cdf7cce 187 /** Stops and clears an mbos timer.
AndrewL 0:1dafafe7d505 188 *
AndrewL 2:af930cdf7cce 189 * @param timerid The ID of the timer to clear.
AndrewL 0:1dafafe7d505 190 */
AndrewL 0:1dafafe7d505 191 void ClearTimer(uint timerid);
AndrewL 0:1dafafe7d505 192
AndrewL 2:af930cdf7cce 193 /** Creates an mbos resource. Allocates and initialises the data structures for the Resource.
AndrewL 0:1dafafe7d505 194 *
AndrewL 2:af930cdf7cce 195 * @param resourceid Unique ID for the resource (0 .. nresource).
AndrewL 2:af930cdf7cce 196 * @param priority Priority of the resource (normally > than that of any task using the
AndrewL 2:af930cdf7cce 197 * resource).
AndrewL 0:1dafafe7d505 198 */
AndrewL 0:1dafafe7d505 199 void CreateResource(uint resourceid, uint priority);
AndrewL 0:1dafafe7d505 200
AndrewL 2:af930cdf7cce 201 /** Locks an mbos resource and temporarily allocates the resource's priority to the calling
AndrewL 2:af930cdf7cce 202 * task.
AndrewL 2:af930cdf7cce 203 * Does nothing if the resource is already locked, or if called from the idle task.
AndrewL 0:1dafafe7d505 204 *
AndrewL 2:af930cdf7cce 205 * @param resourceid The ID of the resource to lock.
AndrewL 2:af930cdf7cce 206 * @returns Zero if the resource was locked successfully, or the ID of the task that is
AndrewL 2:af930cdf7cce 207 * currently locking the resource, if not.
AndrewL 0:1dafafe7d505 208 */
AndrewL 0:1dafafe7d505 209 uint LockResource(uint resourceid);
AndrewL 0:1dafafe7d505 210
AndrewL 2:af930cdf7cce 211 /** Tests whether a resource is locked or free, without changing its state.
AndrewL 0:1dafafe7d505 212 *
AndrewL 2:af930cdf7cce 213 * @param resourceid The ID of the resouce to test.
AndrewL 2:af930cdf7cce 214 * @returns Zero if the resource is free, or the ID of the task that is currently
AndrewL 2:af930cdf7cce 215 * locking the resouce , if not.
AndrewL 0:1dafafe7d505 216
AndrewL 0:1dafafe7d505 217 */
AndrewL 0:1dafafe7d505 218 uint TestResource(uint resourceid);
AndrewL 0:1dafafe7d505 219
AndrewL 0:1dafafe7d505 220 /** Frees a resource
AndrewL 2:af930cdf7cce 221 * Frees an mbos resource and restores the calling task's original priority. Does nothing
AndrewL 2:af930cdf7cce 222 * if the resource is already free, if called from the idle task, or the resource was
AndrewL 2:af930cdf7cce 223 * locked by a different task.
AndrewL 0:1dafafe7d505 224 *
AndrewL 2:af930cdf7cce 225 * @param resourceid The ID of the resource t free.
AndrewL 2:af930cdf7cce 226 * @returns Zero if the resource was freed successfully, or the ID of the task that is
AndrewL 2:af930cdf7cce 227 * locking the resource, if not.
AndrewL 0:1dafafe7d505 228 */
AndrewL 0:1dafafe7d505 229 uint FreeResource(uint resource);
AndrewL 0:1dafafe7d505 230
AndrewL 0:1dafafe7d505 231 private:
AndrewL 0:1dafafe7d505 232 uint* _initstack(uint *stack, void (*fun)());
AndrewL 0:1dafafe7d505 233 };
AndrewL 0:1dafafe7d505 234 #endif