Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

mbos.h

Committer:
AndrewL
Date:
2010-12-05
Revision:
1:b453bba9c5c0
Parent:
0:1dafafe7d505
Child:
2:af930cdf7cce

File content as of revision 1:b453bba9c5c0:

/***********************************************************************************
 *  m b o s   R T O S   F O R    m b e d  (ARM CORTEX M3)
 *
 * Copyright (c) 2010 - 2011 Andrew Levido
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef MBOS_H
#define MBOS_H

typedef unsigned int uint;

/**A pre-emptive, mutlitasking real-time operating system for mbed applications.
 *
 * Allows the user to write their application in the form of independant tasks.
 * The operating system manages a completely separate processor context for each
 * task (processor registers and stack) and swaps between the tasks according to a
 * simple scheduling algorithm.
 *
 * Tasks are allocated a priority, and the scheduler ensures that the task
 * that with the highest priority that is not waiting for an event, has control of
 * the processor. If more than one task shares the highest priority, they will be
 * run sequentially in round-robin fashion.
 *
 * Each task may wait for one or more of up to 32 different events, each represented by
 * one bit in the event flags word. Events may be posted by another task, by a mbos
 * timer, or in response to some asynchronous event such as an peripheral interrupt.
 *
 * mbos implements the SysTick timer to generate a System Tick every millisecond.
 * Scheduling occurs once every Tick, or whenever a task blocks or an event is posted.
 * The user may create one-shot or continuous timers to post events to tasks.
 *
 * mbos implements a simple ceiling protocol resource locking mechanism To manage access
 * to system resources. Tasks may take exclusive ownership of resources for a period.
 *
 * A typical simple example with two tasks, and one timer, might look like this:
 * @code
 * #include "mbed.h"
 * #include "mbos.h"
 *
 * #define TASK1_ID                1        // defines to make the code more readable
 * #define TASK1_PRIO            50
 * #define TASK1_STACK_SZ        32
 * #define TASK2_ID                2
 * #define TASK2_PRIO            60
 * #define TASK2_STACK_SZ        32
 * #define TIMER0_ID            0
 * #define TIMER0_PERIOD        1000
 * #define TIMER0_EVENT            1
 * #define T1_TO_T2_EVENT        2
 *
 * void task1(void);                    // task function prototypes
 * void task2(void);
 *
 * DigitalOut led1(LED1);
 * DigitalOut led2(LED2);
 * mbos os(2, 1);                        // 2 tasks, 1 timer
 *
 * int main(void)
 * {
 *     os.CreateTask(TASK1_ID, TASK1_PRIO, TASK1_STACK_SZ, task1);
 *     os.CreateTask(TASK2_ID, TASK2_PRIO, TASK2_STACK_SZ, task2);
 *     os.CreateTimer(TIMER0_ID, TIMER0_EVENT, TASK1_ID);
 *     os.Start();
 *     // never get here!
 * }
 * void task1(void)
 * {
 *     os.SetTimer(TIMER0_ID, TIMER0_PERIOD, TIMER0_PERIOD);
 *     while(1){
 *             os.WaitEvent(TIMER0_EVENT);
 *             led1 = !led1;
 *             os.SetEvent(T1_TO_T2_EVENT, TASK2_ID);
 *       }
 * }
 * void task2(void)
 * {
 *         while(1){
 *             os.WaitEvent(T1_TO_T2_EVENT);
 *             led2 = 1;
 *             wait_ms(100);
 *             led2 = 0;
 *         }
 * }
 * @endcode
 */

class mbos {
public:
    /** Create an mbos object. Instantiate mbos and define the number of tasks, timers and resources. 
     *
     * @param ntasks The number of user tasks (1 .. 99) in the application. 
     * @param ntimers Optional number of timers (0 ..  100) in the application.
     * @param nresources Optional number of resources (0 .. 100) in the application.
     */
    mbos(uint ntasks, uint ntimers = 0, uint nresources = 0);

    /** Start mbos. Optionally specify the size of the stack for a user-written idle task. All tasks, 
     * timers and resources must be created before calling Start. 
     *
     * @param idlestacksize Size in words (≥32) of the user-written idle stack, if present. 
     * @returns Never returns
     */
    void Start(uint idlestacksize = 0);

    /** Create a mboss task. Allocates and initialises the Task Control Block and task's private stack.
     *
     * @param taskid Unique ID (1 .. number specified in the constructor) for the task.
     * @param priority Priority (0 .. 99) of the task. Tasks may share the same priority.
     * @param stacksize Size in words (>= 32) of the task'sstack.
     * @param fun Pointer to the task function. Function must be static, of type void, returning  void.
     */
    void CreateTask(uint taskid, uint priority, uint stacksz, void (*fun)(void));

    /** Get the ID of the current task
     * Returns the ID of the calling task
     *
     * @returns The ID (0 .. 99) of the calling task
     */
    uint GetTask(void);

    /** Set the priority of the current task. Does not force a context switch. Does nothing if called from the idle task.
     *
     * @param priority Priority (0 .. 99) to apply to the calling task.
     */
    void SetPriority(uint priority);

    /** Get the priority of the current task.
     *
     * @returns The priority (0 .. 99) of the calling task
     */
    uint GetPriority(void);

    /** 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.
     *
     * @param event Event flag(s) to wait for.
     */
    void WaitEvent(uint event);

    /** Post an event or events to a soecified task.
     * 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.
     *
     * @param event Event flag(s) to post. 
     * @param task The ID of the task to which to post the event(s). May not be idle task.
     */
    void SetEvent(uint event, uint task);

    /** Get the event flags
     * Returns the event flag(s) which caused the task to unblock the most recent time.
     *
     * @returns The event flags.
     */
    uint GetEvent(void);

    /** Create a mbos timer
     * Allocates and initialises the Timer Control Block.
     *
     * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer . 
     * @param taskid The ID of the  task to which the timer will post events. May not be idle task.
     * @param event The event flag(s) that the timer should post on timeout. May not be NULL.
     */
    void CreateTimer(uint timerid, uint taskid, uint event);

    /** Set a timer
     * 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.
     *
     * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer . 
     * @param time The period in milliseconds before the timer times out.
     * @param reload The optional time to reload into the timer when it times out.
     */
    void SetTimer(uint timerid, uint time, uint reload = 0);

    /** Clear a timer
     * Stops and clears an mbos timer.
     *
     * @param timerid Unique ID (0 .. the number specified in the constructor - 1) of the timer. 
     */
    void ClearTimer(uint timerid);

    /** Create a mbos resource
     * Creates a mbos resource. Allocates and initialises the Resource Control Block.
     *
     * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource. 
     * @param priority Priority of the resource (should be > than that of any task using the resource).
     */
    void CreateResource(uint resourceid, uint priority);

    /** Lock a resource
     *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.
     *
     * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource. 
     * @returns Zero, if the resource was locked successfully or the id of the task locking the resource, if not.
     */
    uint LockResource(uint resourceid);

    /** Test a resource
     * Checks whether a resource is locked or free, without changing its state.
     *
     * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource. 
     * @returns The ID of the task which has locked the resource, or zero if the resource is free.

     */
    uint TestResource(uint resourceid);

    /** Frees a resource
     * 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..
     *
     * @param resourceid Unique ID (0 .. the number specified in the constructor - 1) of the resource. 
     * @returns Zero, if the resource was freed successfully or the id of the task locking the resource if not.
     */
    uint FreeResource(uint resource);

private:
    uint* _initstack(uint *stack, void (*fun)());
};
#endif