Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Committer:
AndrewL
Date:
Sun Dec 05 10:34:48 2010 +0000
Revision:
1:b453bba9c5c0
Parent:
0:1dafafe7d505
Child:
2:af930cdf7cce
v1.0b
updated doxygen

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 1:b453bba9c5c0 98 /** Create an mbos object. Instantiate mbos and define the number of tasks, timers and resources.
AndrewL 0:1dafafe7d505 99 *
AndrewL 0:1dafafe7d505 100 * @param ntasks The number of user tasks (1 .. 99) in the application.
AndrewL 0:1dafafe7d505 101 * @param ntimers Optional number of timers (0 .. 100) in the application.
AndrewL 0:1dafafe7d505 102 * @param nresources Optional number of resources (0 .. 100) in the application.
AndrewL 0:1dafafe7d505 103 */
AndrewL 0:1dafafe7d505 104 mbos(uint ntasks, uint ntimers = 0, uint nresources = 0);
AndrewL 0:1dafafe7d505 105
AndrewL 1:b453bba9c5c0 106 /** Start mbos. Optionally specify the size of the stack for a user-written idle task. All tasks,
AndrewL 1:b453bba9c5c0 107 * timers and resources must be created before calling Start.
AndrewL 0:1dafafe7d505 108 *
AndrewL 0:1dafafe7d505 109 * @param idlestacksize Size in words (≥32) of the user-written idle stack, if present.
AndrewL 0:1dafafe7d505 110 * @returns Never returns
AndrewL 0:1dafafe7d505 111 */
AndrewL 0:1dafafe7d505 112 void Start(uint idlestacksize = 0);
AndrewL 0:1dafafe7d505 113
AndrewL 1:b453bba9c5c0 114 /** Create a mboss task. Allocates and initialises the Task Control Block and task's private stack.
AndrewL 0:1dafafe7d505 115 *
AndrewL 0:1dafafe7d505 116 * @param taskid Unique ID (1 .. number specified in the constructor) for the task.
AndrewL 0:1dafafe7d505 117 * @param priority Priority (0 .. 99) of the task. Tasks may share the same priority.
AndrewL 1:b453bba9c5c0 118 * @param stacksize Size in words (>= 32) of the task'sstack.
AndrewL 0:1dafafe7d505 119 * @param fun Pointer to the task function. Function must be static, of type void, returning void.
AndrewL 0:1dafafe7d505 120 */
AndrewL 0:1dafafe7d505 121 void CreateTask(uint taskid, uint priority, uint stacksz, void (*fun)(void));
AndrewL 0:1dafafe7d505 122
AndrewL 0:1dafafe7d505 123 /** Get the ID of the current task
AndrewL 0:1dafafe7d505 124 * Returns the ID of the calling task
AndrewL 0:1dafafe7d505 125 *
AndrewL 0:1dafafe7d505 126 * @returns The ID (0 .. 99) of the calling task
AndrewL 0:1dafafe7d505 127 */
AndrewL 0:1dafafe7d505 128 uint GetTask(void);
AndrewL 0:1dafafe7d505 129
AndrewL 1:b453bba9c5c0 130 /** Set the priority of the current task. Does not force a context switch. Does nothing if called from the idle task.
AndrewL 0:1dafafe7d505 131 *
AndrewL 0:1dafafe7d505 132 * @param priority Priority (0 .. 99) to apply to the calling task.
AndrewL 0:1dafafe7d505 133 */
AndrewL 0:1dafafe7d505 134 void SetPriority(uint priority);
AndrewL 0:1dafafe7d505 135
AndrewL 1:b453bba9c5c0 136 /** Get the priority of the current task.
AndrewL 0:1dafafe7d505 137 *
AndrewL 0:1dafafe7d505 138 * @returns The priority (0 .. 99) of the calling task
AndrewL 0:1dafafe7d505 139 */
AndrewL 0:1dafafe7d505 140 uint GetPriority(void);
AndrewL 0:1dafafe7d505 141
AndrewL 1:b453bba9c5c0 142 /** Wait for an event or events. Causes the current task to block, waiting for the specified event. Does nothing if called from the idle task, or if event is NULL.
AndrewL 0:1dafafe7d505 143 *
AndrewL 1:b453bba9c5c0 144 * @param event Event flag(s) to wait for.
AndrewL 0:1dafafe7d505 145 */
AndrewL 0:1dafafe7d505 146 void WaitEvent(uint event);
AndrewL 0:1dafafe7d505 147
AndrewL 0:1dafafe7d505 148 /** Post an event or events to a soecified task.
AndrewL 0:1dafafe7d505 149 * Posts the nominated event(s) to the specified task. Forces a context switch if the events are posted successfully. Does nothing if the task is not waiting, or is not waiting for the posted event.
AndrewL 0:1dafafe7d505 150 *
AndrewL 0:1dafafe7d505 151 * @param event Event flag(s) to post.
AndrewL 0:1dafafe7d505 152 * @param task The ID of the task to which to post the event(s). May not be idle task.
AndrewL 0:1dafafe7d505 153 */
AndrewL 0:1dafafe7d505 154 void SetEvent(uint event, uint task);
AndrewL 0:1dafafe7d505 155
AndrewL 0:1dafafe7d505 156 /** Get the event flags
AndrewL 0:1dafafe7d505 157 * Returns the event flag(s) which caused the task to unblock the most recent time.
AndrewL 0:1dafafe7d505 158 *
AndrewL 0:1dafafe7d505 159 * @returns The event flags.
AndrewL 0:1dafafe7d505 160 */
AndrewL 0:1dafafe7d505 161 uint GetEvent(void);
AndrewL 0:1dafafe7d505 162
AndrewL 0:1dafafe7d505 163 /** Create a mbos timer
AndrewL 0:1dafafe7d505 164 * Allocates and initialises the Timer Control Block.
AndrewL 0:1dafafe7d505 165 *
AndrewL 0:1dafafe7d505 166 * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer .
AndrewL 0:1dafafe7d505 167 * @param taskid The ID of the task to which the timer will post events. May not be idle task.
AndrewL 0:1dafafe7d505 168 * @param event The event flag(s) that the timer should post on timeout. May not be NULL.
AndrewL 0:1dafafe7d505 169 */
AndrewL 0:1dafafe7d505 170 void CreateTimer(uint timerid, uint taskid, uint event);
AndrewL 0:1dafafe7d505 171
AndrewL 0:1dafafe7d505 172 /** Set a timer
AndrewL 0:1dafafe7d505 173 * Starts an mbos timer. If the reload time is zero or omitted, the timer will be reset once it has posted a single event, after time milliseconds. If the reload time is non-zero, this value will be loaded into the timer on time-out, and the timer will continue indefinitely. In this case the interval to the first event will be time, and the interval between subsequent events will be reloadtime.
AndrewL 0:1dafafe7d505 174 *
AndrewL 0:1dafafe7d505 175 * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer .
AndrewL 0:1dafafe7d505 176 * @param time The period in milliseconds before the timer times out.
AndrewL 0:1dafafe7d505 177 * @param reload The optional time to reload into the timer when it times out.
AndrewL 0:1dafafe7d505 178 */
AndrewL 0:1dafafe7d505 179 void SetTimer(uint timerid, uint time, uint reload = 0);
AndrewL 0:1dafafe7d505 180
AndrewL 0:1dafafe7d505 181 /** Clear a timer
AndrewL 0:1dafafe7d505 182 * Stops and clears an mbos timer.
AndrewL 0:1dafafe7d505 183 *
AndrewL 0:1dafafe7d505 184 * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer.
AndrewL 0:1dafafe7d505 185 */
AndrewL 0:1dafafe7d505 186 void ClearTimer(uint timerid);
AndrewL 0:1dafafe7d505 187
AndrewL 0:1dafafe7d505 188 /** Create a mbos resource
AndrewL 0:1dafafe7d505 189 * Creates a mbos resource. Allocates and initialises the Resource Control Block.
AndrewL 0:1dafafe7d505 190 *
AndrewL 0:1dafafe7d505 191 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 192 * @param priority Priority of the resource (should be > than that of any task using the resource).
AndrewL 0:1dafafe7d505 193 */
AndrewL 0:1dafafe7d505 194 void CreateResource(uint resourceid, uint priority);
AndrewL 0:1dafafe7d505 195
AndrewL 0:1dafafe7d505 196 /** Lock a resource
AndrewL 1:b453bba9c5c0 197 *Locks a mbos resource by temporarily allocating the resource's priority to the calling task. This priority should be higher than that of any other task potentially accessing the resource. Does nothing if the resource is already locked, or if called from the idle task.
AndrewL 0:1dafafe7d505 198 *
AndrewL 0:1dafafe7d505 199 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 200 * @returns Zero, if the resource was locked successfully or the id of the task locking the resource, if not.
AndrewL 0:1dafafe7d505 201 */
AndrewL 0:1dafafe7d505 202 uint LockResource(uint resourceid);
AndrewL 0:1dafafe7d505 203
AndrewL 0:1dafafe7d505 204 /** Test a resource
AndrewL 0:1dafafe7d505 205 * Checks whether a resource is locked or free, without changing its state.
AndrewL 0:1dafafe7d505 206 *
AndrewL 0:1dafafe7d505 207 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 208 * @returns The ID of the task which has locked the resource, or zero if the resource is free.
AndrewL 0:1dafafe7d505 209
AndrewL 0:1dafafe7d505 210 */
AndrewL 0:1dafafe7d505 211 uint TestResource(uint resourceid);
AndrewL 0:1dafafe7d505 212
AndrewL 0:1dafafe7d505 213 /** Frees a resource
AndrewL 1:b453bba9c5c0 214 * Frees an mbos resource and restores the calling task's original priority. Does nothing if the resource is already free, if called from the idle task, or the resource was locked by a different task..
AndrewL 0:1dafafe7d505 215 *
AndrewL 0:1dafafe7d505 216 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 217 * @returns Zero, if the resource was freed successfully or the id of the task locking the resource if not.
AndrewL 0:1dafafe7d505 218 */
AndrewL 0:1dafafe7d505 219 uint FreeResource(uint resource);
AndrewL 0:1dafafe7d505 220
AndrewL 0:1dafafe7d505 221 private:
AndrewL 0:1dafafe7d505 222 uint* _initstack(uint *stack, void (*fun)());
AndrewL 0:1dafafe7d505 223 };
AndrewL 0:1dafafe7d505 224 #endif