A Small Cooperative Multitasking Kernel

Dependencies:   mbed

Revision:
0:73b89fc74e9f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel.h	Sun Jul 24 17:15:42 2011 +0000
@@ -0,0 +1,59 @@
+/* Opus Una - A Small Cooperative Multitasking Kernel in C
+ *
+ * Copyright (C) 2011 by Ivo van Poorten <ivop@euronet.nl>
+ * This file is licensed under the terms of the GNU Lesser
+ * General Public License, version 3.
+ */
+
+#ifndef OU_KERNEL_H
+#define OU_KERNEL_H
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define OU_VERSION      1
+
+#define OU_CONCAT2(x,y) x##y
+#define OU_CONCAT(x,y)  OU_CONCAT2(x,y)
+
+#define OU_TASK(name) static void name(void) { if(ou_state) goto *ou_state; {
+#define OU_ENDTASK    OU_SUSPEND; ou_wait=0; }}
+
+#define OU_WAIT(ticks) { ou_wait = ticks; ou_state = &&OU_CONCAT(L,__LINE__); return; } \
+    OU_CONCAT(L,__LINE__):
+
+#define OU_YIELD    do{ OU_WAIT(0); }while(0)
+#define OU_SUSPEND  do{ ou_tasks[ou_current_task].suspended = 1; OU_WAIT(0); }while(0)
+#define OU_START(t) do{ ou_tasks[t].suspended = 0; OU_WAIT(0); }while(0)
+
+#define OU_GET_TASK_PRIORITY(t)     ou_tasks[t].priority
+#define OU_SET_TASK_PRIORITY(t,p)   ou_tasks[t].priority = p
+
+#define OU_GET_MY_PRIORITY()        OU_GET_TASK_PRIORITY(ou_current_task)
+#define OU_SET_MY_PRIORITY(p)       OU_SET_TASK_PRIORITY(ou_current_task,p)
+
+// Note: Locks only work between tasks, NOT between tasks and interrupt handlers.
+// For that, we need a full-blown mutex
+
+#define OU_LOCK(i)      while(!i) OU_WAIT(1); i=1
+#define OU_UNLOCK(i)    i=0
+
+struct ou_task {
+    void (*function)(void);             // entry point of task
+    volatile unsigned priority,         // 0 is highest, UINT_MAX-1 is lowest
+                      suspended,        // task is suspended (=1)
+                      wait;             // ticks to wait before running again
+    unsigned delayed;                   // # of times scheduling was delayed
+    void *state;                        // current state within function
+};
+
+void ou_update_tasks(void);             // called from timer interrupt
+void ou_scheduler(void);                // main loop
+
+extern struct ou_task ou_tasks[];
+extern void *ou_state;
+extern unsigned ou_wait, ou_current_task, ou_ticks;
+extern const unsigned ou_ntasks;
+
+#endif