A Small Cooperative Multitasking Kernel

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers kernel.h Source File

kernel.h

00001 /* Opus Una - A Small Cooperative Multitasking Kernel in C
00002  *
00003  * Copyright (C) 2011 by Ivo van Poorten <ivop@euronet.nl>
00004  * This file is licensed under the terms of the GNU Lesser
00005  * General Public License, version 3.
00006  */
00007 
00008 #ifndef OU_KERNEL_H
00009 #define OU_KERNEL_H
00010 
00011 #ifndef NULL
00012 #define NULL ((void *)0)
00013 #endif
00014 
00015 #define OU_VERSION      1
00016 
00017 #define OU_CONCAT2(x,y) x##y
00018 #define OU_CONCAT(x,y)  OU_CONCAT2(x,y)
00019 
00020 #define OU_TASK(name) static void name(void) { if(ou_state) goto *ou_state; {
00021 #define OU_ENDTASK    OU_SUSPEND; ou_wait=0; }}
00022 
00023 #define OU_WAIT(ticks) { ou_wait = ticks; ou_state = &&OU_CONCAT(L,__LINE__); return; } \
00024     OU_CONCAT(L,__LINE__):
00025 
00026 #define OU_YIELD    do{ OU_WAIT(0); }while(0)
00027 #define OU_SUSPEND  do{ ou_tasks[ou_current_task].suspended = 1; OU_WAIT(0); }while(0)
00028 #define OU_START(t) do{ ou_tasks[t].suspended = 0; OU_WAIT(0); }while(0)
00029 
00030 #define OU_GET_TASK_PRIORITY(t)     ou_tasks[t].priority
00031 #define OU_SET_TASK_PRIORITY(t,p)   ou_tasks[t].priority = p
00032 
00033 #define OU_GET_MY_PRIORITY()        OU_GET_TASK_PRIORITY(ou_current_task)
00034 #define OU_SET_MY_PRIORITY(p)       OU_SET_TASK_PRIORITY(ou_current_task,p)
00035 
00036 // Note: Locks only work between tasks, NOT between tasks and interrupt handlers.
00037 // For that, we need a full-blown mutex
00038 
00039 #define OU_LOCK(i)      while(!i) OU_WAIT(1); i=1
00040 #define OU_UNLOCK(i)    i=0
00041 
00042 struct ou_task {
00043     void (*function)(void);             // entry point of task
00044     volatile unsigned priority,         // 0 is highest, UINT_MAX-1 is lowest
00045                       suspended,        // task is suspended (=1)
00046                       wait;             // ticks to wait before running again
00047     unsigned delayed;                   // # of times scheduling was delayed
00048     void *state;                        // current state within function
00049 };
00050 
00051 void ou_update_tasks(void);             // called from timer interrupt
00052 void ou_scheduler(void);                // main loop
00053 
00054 extern struct ou_task ou_tasks[];
00055 extern void *ou_state;
00056 extern unsigned ou_wait, ou_current_task, ou_ticks;
00057 extern const unsigned ou_ntasks;
00058 
00059 #endif