Simple cooperative operating system

Dependencies:   mbed

main.cpp

Committer:
akouz
Date:
2013-09-17
Revision:
4:690def0f4387
Parent:
3:85a9253b7559

File content as of revision 4:690def0f4387:

#include "mbed.h"
#include "coos.h"

//##########################################################
// var
//##########################################################
Ticker flipper;
DigitalOut led1(LED1);
DigitalOut led2(LED2);

jmp_buf         COOS_main_context;
jmp_buf         COOS_task_context[MAX_TASKS];     /* store environment for tasks */
volatile int    COOS_task_no;
volatile int    COOS_task_delay[MAX_TASKS];       /* task delay in 1 ms ticks, task stopped if value is negative */

//##########################################################
// func
//##########################################################

// ======================================================
// Task 0
// ======================================================
void COOS_task0(void){
    while(1) {
        led2 = !led2;
        DELAY(1000);
    }
};
// ======================================================
// Task 1
// ======================================================
void COOS_task1(void){
    while(1){
        led1 = !led1;
        DELAY(500);
    }
};
// ======================================================
// Task 2
// ======================================================
void COOS_task2(void){
    DELAY(STOP);
};
// ======================================================
// Task 3
// ======================================================
void COOS_task3(void){
    DELAY(STOP);
};
// ======================================================
// Task 4
// ======================================================
void COOS_task4(void){
    DELAY(STOP);
};
// ======================================================
// Task 5
// ======================================================
void COOS_task5(void){
    DELAY(STOP);
};
// ======================================================
// Task 6
// ======================================================
void COOS_task6(void){
    DELAY(STOP);
};
// ======================================================
// Task 7
// ======================================================
void COOS_task7(void){
    DELAY(STOP);
};

// ======================================================
// Shutdown task No
// ======================================================
 void shutdown_task(int task_No) {
    COOS_task_delay[task_No] = STOP;        // sleep forever
}

// ======================================================
// Wake-up task No
// ======================================================
void wake_up_task(int task_No) {
    if (COOS_task_delay[task_No] < 0){
        COOS_task_delay[task_No] = 0;       // run
    }           
}
// ======================================================
// Timer
// ======================================================
void tick_1ms() {
    int i;
    for (i=0; i<MAX_TASKS; i++){
        if (COOS_task_delay[i] > 0){ // if task not stopped
            COOS_task_delay[i]--;   // decrement its delay
        }
    } // for
}

// ======================================================
// Main
// ======================================================
int main(void) {
    int   sjres;
    // -----------------------
    // Init 1 ms tick
    // -----------------------    
    flipper.attach(&tick_1ms, 0.001); 

    // -----------------------
    // Init tasks
    // -----------------------
    for (COOS_task_no=0; COOS_task_no<MAX_TASKS; COOS_task_no++) {
        sjres = setjmp(COOS_main_context);
        if (sjres == 0) {
            switch (COOS_task_no & 0x07) { 
                case 0 :  COOS_task0();  break;   
                case 1 :  COOS_task1();  break;   
                case 2 :  COOS_task2();  break;   
                case 3 :  COOS_task3();  break;   
                case 4 :  COOS_task4();  break;   
                case 5 :  COOS_task5();  break;   
                case 6 :  COOS_task6();  break;   
                case 7 :  COOS_task7();  break;   
            } // switch
        } else {
            COOS_task_delay[COOS_task_no] = --sjres;
        }
    } // for
    // -----------------------
    // Scheduler loop
    // -----------------------
    COOS_task_no = 0;
    while(1) {
        if (COOS_task_delay[COOS_task_no] == 0) {               /* if task is active */
            sjres = setjmp(COOS_main_context);                  /* set return point and get delay value from the task */
            if (sjres == 0){                                    /* after setting return point */
                longjmp(COOS_task_context[COOS_task_no], 1);    /* invoke task */
            } else {                                            /* after returning from task */
                COOS_task_delay[COOS_task_no] = --sjres;        /* set task delay (if negative delay - then task stopped) */
            }
        }
        COOS_task_no++;         
        if (COOS_task_no >= MAX_TASKS){
            COOS_task_no = 0;
        }
    } // while
} // main

/* EOF */