A simple Round Robin Task scheduler (a sub minimalistic Operating System) with no inter Task communication implemented (semaphores, mailboxes etc) nor task local varibales can be used. They have to be global (static). But, it's the first step up to an OS.

Dependencies:   mbed

main.c

Committer:
Stanislaus
Date:
2010-06-11
Revision:
0:9ce7c170cb66

File content as of revision 0:9ce7c170cb66:

#include "mbed.h"
#include "scheduler.h"

#define ON  1
#define OFF 0

DigitalOut myLED(LED1);         // LED for task A and B
DigitalOut myLEDTaskC(LED2);    // LED for Task C
DigitalOut myLEDTaskD(LED3);    // LED for Task D
DigitalOut myLEDTaskE(LED4);    // LED for Task E

Timer t;
Ticker keepAlive;

// *******************************************************************************
// * @brief       "taskA" task code
// * @param[in]   None
// * @param[out]  None
// * @retval      bool
// * @par Description
// * @details    This task use to print message "taskA running". Indicate "taskA"
// *             had been executed.
// *******************************************************************************
bool taskA(void* pData) 
{
    static unsigned int cnt_numA = 0;

    myLED = ON;
    cnt_numA++;

    return true;
}

// *******************************************************************************
// * @brief       "taskB" task code
// * @param[in]   None
// * @param[out]  None
// * @retval      bool
// * @par Description
// * @details    This task use to print message "taskB running". Indicate "taskB"
// *             had been executed.
// *******************************************************************************
bool taskB(void* pData) 
{
    static unsigned int cnt_numB = 0;

    myLED = OFF;
    cnt_numB++;

    return true;
}

// *******************************************************************************
// * @brief       "taskC" task code
// * @param[in]   None
// * @param[out]  None
// * @retval      bool
// * @par Description
// * @details    This task use to print message "tasC running". Indicate "taskC"
// *             had been executed.
// *******************************************************************************
bool taskC(void* pData) 
{
    static unsigned int cnt_numC = 0;

    myLEDTaskC = !myLEDTaskC.read();
    cnt_numC++;

    return true;
}

// *******************************************************************************
// * @brief       "taskD" task code
// * @param[in]   None
// * @param[out]  None
// * @retval      bool
// * @par Description
// * @details    This task use to print message "taskB running". Indicate "taskD"
// *             had been executed.
// *******************************************************************************
bool taskD(void* pData) 
{
    static unsigned int cnt_numD = 0;

    myLEDTaskD = !myLEDTaskD.read();
    cnt_numD++;

    return true;
}

// *******************************************************************************
// * @brief       "taskE" task code
// * @param[in]   None
// * @param[out]  None
// * @retval      bool
// * @par Description
// * @details    This task use to print message "taskE running". Indicate "taskE"
// *             had been executed.
// *******************************************************************************
bool taskE(void* pData) 
{
    static unsigned int cnt_numE = 0;

    myLEDTaskE = !myLEDTaskE.read();
    cnt_numE++;

    return true;
}

// *******************************************************************************
// * @brief       "taskF" task code
// * @param[in]   None
// * @param[out]  None
// * @retval      bool
// * @par Description
// * @details    This task use to print message "taskF running". Indicate "taskF"
// *             had been executed.
// *******************************************************************************
bool taskF(void* pData) 
{
    static unsigned int cnt_numF = 0;

    cnt_numF++;     // task is only running for 30 seconds -> cnt_numF has the value 5 than

    return true;
}

// *******************************************************************************
// * @brief       "runningTasks" a Ticker routine 
// * @param[in]   None
// * @param[out]  None
// * @retval      None
// * @par Description
// * @details    This method is used to keep the scheduler alife
// *             
// *******************************************************************************
void runningTasks() 
{
    // you can do this here in running Tasks or in the main routine while loop -> see below
    schedulerRun(t.read_ms());  
}

int main() 
{
    schedulerInit();        // init and start scheduler

    t.start();              // start task timer

    int handleTaskA = schedulerAddTask(t.read_ms(), 0, 500,  (taskfuncptr) taskA);  // Task A is switching LED1 on
    int handleTaskB = schedulerAddTask(t.read_ms(), 0, 1000, (taskfuncptr) taskB);  // Task B is switching LED1 off
    int handleTaskC = schedulerAddTask(t.read_ms(), 0, 200,  (taskfuncptr) taskC);  // Task C is switching LED2 on and off - every 200 ms -> five times per sec.
    int handleTaskD = schedulerAddTask(t.read_ms(), 0, 100,  (taskfuncptr) taskD);  // Task D is switching LED3 on anf off - every 100 ms -> ten times per sec.
    int handleTaskE = schedulerAddTask(t.read_ms(), 0, 500,  (taskfuncptr) taskE);  // Task E is switching LED4 on and off - vice versa to LED1 -> starting with on
    int handleTaskF = schedulerAddTask(t.read_ms(), 6, 5000, (taskfuncptr) taskF);  // Task F finished after 30 seconds 
    

    // the address of the function to be attached (runTasks) and the interval (,5 micro seconds)
    keepAlive.attach_us(&runningTasks, 500); 
    
    while (1) 
    {
        //// we can feed the scheduler here, too 
        ////schedulerRun(t.read_ms());
        ////wait(0.001);                        //wait one ms
        // with a short delay we can power down the controller here...
        // or poll very fast variables that are set in interrupt service routines (ISR's) etc.
    }
    // The code don't reach here -> if so, a great mess occured
}