Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Committer:
AndrewL
Date:
Sat Dec 04 16:51:52 2010 +0000
Revision:
0:1dafafe7d505
Child:
1:b453bba9c5c0
1.1a
changed name to mbos, simplified errors, updated doxygen comments, removed returncodes from resource management

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 0:1dafafe7d505 49 * #define TASK1_ID 1 // defines to make the code more readable
AndrewL 0:1dafafe7d505 50 * #define TASK1_PRIO 50
AndrewL 0:1dafafe7d505 51 * #define TASK1_STACK_SZ 32
AndrewL 0:1dafafe7d505 52 * #define TASK2_ID 2
AndrewL 0:1dafafe7d505 53 * #define TASK2_PRIO 60
AndrewL 0:1dafafe7d505 54 * #define TASK2_STACK_SZ 32
AndrewL 0:1dafafe7d505 55 * #define TIMER0_ID 0
AndrewL 0:1dafafe7d505 56 * #define TIMER0_PERIOD 1000
AndrewL 0:1dafafe7d505 57 * #define TIMER0_EVENT 1
AndrewL 0:1dafafe7d505 58 * #define T1_TO_T2_EVENT 2
AndrewL 0:1dafafe7d505 59 *
AndrewL 0:1dafafe7d505 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 0:1dafafe7d505 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 0:1dafafe7d505 79 * os.WaitEvent(TIMER0_EVENT);
AndrewL 0:1dafafe7d505 80 * led1 = !led1;
AndrewL 0:1dafafe7d505 81 * os.SetEvent(T1_TO_T2_EVENT, TASK2_ID);
AndrewL 0:1dafafe7d505 82 * }
AndrewL 0:1dafafe7d505 83 * }
AndrewL 0:1dafafe7d505 84 * void task2(void)
AndrewL 0:1dafafe7d505 85 * {
AndrewL 0:1dafafe7d505 86 * while(1){
AndrewL 0:1dafafe7d505 87 * os.WaitEvent(T1_TO_T2_EVENT);
AndrewL 0:1dafafe7d505 88 * led2 = 1;
AndrewL 0:1dafafe7d505 89 * wait_ms(100);
AndrewL 0:1dafafe7d505 90 * led2 = 0;
AndrewL 0:1dafafe7d505 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 0:1dafafe7d505 98 /** Create an mbos object
AndrewL 0:1dafafe7d505 99 * Instantiate mbos and define the number of tasks, timers and resources. Must be called first.
AndrewL 0:1dafafe7d505 100 *
AndrewL 0:1dafafe7d505 101 * @param ntasks The number of user tasks (1 .. 99) in the application.
AndrewL 0:1dafafe7d505 102 * @param ntimers Optional number of timers (0 .. 100) in the application.
AndrewL 0:1dafafe7d505 103 * @param nresources Optional number of resources (0 .. 100) in the application.
AndrewL 0:1dafafe7d505 104 */
AndrewL 0:1dafafe7d505 105 mbos(uint ntasks, uint ntimers = 0, uint nresources = 0);
AndrewL 0:1dafafe7d505 106
AndrewL 0:1dafafe7d505 107 /** Start mbos
AndrewL 0:1dafafe7d505 108 * Optionally specify the size of the stack for a user-written idle task. All tasks, timers and resources must be created before calling Start.
AndrewL 0:1dafafe7d505 109 *
AndrewL 0:1dafafe7d505 110 * @param idlestacksize Size in words (≥32) of the user-written idle stack, 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 0:1dafafe7d505 115 /** Create a mboss task
AndrewL 0:1dafafe7d505 116 * Allocates and initialises the Task Control Block and task’s private stack.
AndrewL 0:1dafafe7d505 117 *
AndrewL 0:1dafafe7d505 118 * @param taskid Unique ID (1 .. number specified in the constructor) for the task.
AndrewL 0:1dafafe7d505 119 * @param priority Priority (0 .. 99) of the task. Tasks may share the same priority.
AndrewL 0:1dafafe7d505 120 * @param stacksize Size in words (≥32) of the task’s stack.
AndrewL 0:1dafafe7d505 121 * @param fun Pointer to the task function. Function must be static, of type void, returning void.
AndrewL 0:1dafafe7d505 122 */
AndrewL 0:1dafafe7d505 123 void CreateTask(uint taskid, uint priority, uint stacksz, void (*fun)(void));
AndrewL 0:1dafafe7d505 124
AndrewL 0:1dafafe7d505 125 /** Get the ID of the current task
AndrewL 0:1dafafe7d505 126 * Returns the ID of the calling task
AndrewL 0:1dafafe7d505 127 *
AndrewL 0:1dafafe7d505 128 * @returns The ID (0 .. 99) of the calling task
AndrewL 0:1dafafe7d505 129 */
AndrewL 0:1dafafe7d505 130 uint GetTask(void);
AndrewL 0:1dafafe7d505 131
AndrewL 0:1dafafe7d505 132 /** Set the priority of the current task
AndrewL 0:1dafafe7d505 133 * Sets the priority of the calling task.Does not force a context switch. May not be called from the idle task.
AndrewL 0:1dafafe7d505 134 *
AndrewL 0:1dafafe7d505 135 * @param priority Priority (0 .. 99) to apply to the calling task.
AndrewL 0:1dafafe7d505 136 */
AndrewL 0:1dafafe7d505 137 void SetPriority(uint priority);
AndrewL 0:1dafafe7d505 138
AndrewL 0:1dafafe7d505 139 /** Get the priority of the current task
AndrewL 0:1dafafe7d505 140 * Returns the priority of the calling task
AndrewL 0:1dafafe7d505 141 *
AndrewL 0:1dafafe7d505 142 * @returns The priority (0 .. 99) of the calling task
AndrewL 0:1dafafe7d505 143 */
AndrewL 0:1dafafe7d505 144 uint GetPriority(void);
AndrewL 0:1dafafe7d505 145
AndrewL 0:1dafafe7d505 146 /** Wait for an event or events
AndrewL 0:1dafafe7d505 147 * Causes the current task to block, waiting for the specified event. May not be called from the idle task.
AndrewL 0:1dafafe7d505 148 *
AndrewL 0:1dafafe7d505 149 * @param event Event flag(s) to wait for. May not be NULL.
AndrewL 0:1dafafe7d505 150 */
AndrewL 0:1dafafe7d505 151 void WaitEvent(uint event);
AndrewL 0:1dafafe7d505 152
AndrewL 0:1dafafe7d505 153 /** Post an event or events to a soecified task.
AndrewL 0:1dafafe7d505 154 * 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 155 *
AndrewL 0:1dafafe7d505 156 * @param event Event flag(s) to post.
AndrewL 0:1dafafe7d505 157 * @param task The ID of the task to which to post the event(s). May not be idle task.
AndrewL 0:1dafafe7d505 158 */
AndrewL 0:1dafafe7d505 159 void SetEvent(uint event, uint task);
AndrewL 0:1dafafe7d505 160
AndrewL 0:1dafafe7d505 161 /** Get the event flags
AndrewL 0:1dafafe7d505 162 * Returns the event flag(s) which caused the task to unblock the most recent time.
AndrewL 0:1dafafe7d505 163 *
AndrewL 0:1dafafe7d505 164 * @returns The event flags.
AndrewL 0:1dafafe7d505 165 */
AndrewL 0:1dafafe7d505 166 uint GetEvent(void);
AndrewL 0:1dafafe7d505 167
AndrewL 0:1dafafe7d505 168 /** Create a mbos timer
AndrewL 0:1dafafe7d505 169 * Allocates and initialises the Timer Control Block.
AndrewL 0:1dafafe7d505 170 *
AndrewL 0:1dafafe7d505 171 * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer .
AndrewL 0:1dafafe7d505 172 * @param taskid The ID of the task to which the timer will post events. May not be idle task.
AndrewL 0:1dafafe7d505 173 * @param event The event flag(s) that the timer should post on timeout. May not be NULL.
AndrewL 0:1dafafe7d505 174 */
AndrewL 0:1dafafe7d505 175 void CreateTimer(uint timerid, uint taskid, uint event);
AndrewL 0:1dafafe7d505 176
AndrewL 0:1dafafe7d505 177 /** Set a timer
AndrewL 0:1dafafe7d505 178 * 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 179 *
AndrewL 0:1dafafe7d505 180 * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer .
AndrewL 0:1dafafe7d505 181 * @param time The period in milliseconds before the timer times out.
AndrewL 0:1dafafe7d505 182 * @param reload The optional time to reload into the timer when it times out.
AndrewL 0:1dafafe7d505 183 */
AndrewL 0:1dafafe7d505 184 void SetTimer(uint timerid, uint time, uint reload = 0);
AndrewL 0:1dafafe7d505 185
AndrewL 0:1dafafe7d505 186 /** Clear a timer
AndrewL 0:1dafafe7d505 187 * Stops and clears an mbos timer.
AndrewL 0:1dafafe7d505 188 *
AndrewL 0:1dafafe7d505 189 * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer.
AndrewL 0:1dafafe7d505 190 */
AndrewL 0:1dafafe7d505 191 void ClearTimer(uint timerid);
AndrewL 0:1dafafe7d505 192
AndrewL 0:1dafafe7d505 193 /** Create a mbos resource
AndrewL 0:1dafafe7d505 194 * Creates a mbos resource. Allocates and initialises the Resource Control Block.
AndrewL 0:1dafafe7d505 195 *
AndrewL 0:1dafafe7d505 196 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 197 * @param priority Priority of the resource (should be > than that of any task using the resource).
AndrewL 0:1dafafe7d505 198 */
AndrewL 0:1dafafe7d505 199 void CreateResource(uint resourceid, uint priority);
AndrewL 0:1dafafe7d505 200
AndrewL 0:1dafafe7d505 201 /** Lock a resource
AndrewL 0:1dafafe7d505 202 *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 203 *
AndrewL 0:1dafafe7d505 204 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 205 * @returns Zero, if the resource was locked successfully or the id of the task locking the resource, if not.
AndrewL 0:1dafafe7d505 206 */
AndrewL 0:1dafafe7d505 207 uint LockResource(uint resourceid);
AndrewL 0:1dafafe7d505 208
AndrewL 0:1dafafe7d505 209 /** Test a resource
AndrewL 0:1dafafe7d505 210 * Checks whether a resource is locked or free, without changing its state.
AndrewL 0:1dafafe7d505 211 *
AndrewL 0:1dafafe7d505 212 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 213 * @returns The ID of the task which has locked the resource, or zero if the resource is free.
AndrewL 0:1dafafe7d505 214
AndrewL 0:1dafafe7d505 215 */
AndrewL 0:1dafafe7d505 216 uint TestResource(uint resourceid);
AndrewL 0:1dafafe7d505 217
AndrewL 0:1dafafe7d505 218 /** Frees a resource
AndrewL 0:1dafafe7d505 219 * 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 220 *
AndrewL 0:1dafafe7d505 221 * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource.
AndrewL 0:1dafafe7d505 222 * @returns Zero, if the resource was freed successfully or the id of the task locking the resource if not.
AndrewL 0:1dafafe7d505 223 */
AndrewL 0:1dafafe7d505 224 uint FreeResource(uint resource);
AndrewL 0:1dafafe7d505 225
AndrewL 0:1dafafe7d505 226 private:
AndrewL 0:1dafafe7d505 227 uint* _initstack(uint *stack, void (*fun)());
AndrewL 0:1dafafe7d505 228 };
AndrewL 0:1dafafe7d505 229 #endif