A Small Cooperative Multitasking Kernel

Dependencies:   mbed

Committer:
Ivop
Date:
Sun Jul 24 17:15:42 2011 +0000
Revision:
0:73b89fc74e9f
first release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ivop 0:73b89fc74e9f 1 /* Opus Una - A Small Cooperative Multitasking Kernel in C
Ivop 0:73b89fc74e9f 2 *
Ivop 0:73b89fc74e9f 3 * Copyright (C) 2011 by Ivo van Poorten <ivop@euronet.nl>
Ivop 0:73b89fc74e9f 4 * This file is licensed under the terms of the GNU Lesser
Ivop 0:73b89fc74e9f 5 * General Public License, version 3.
Ivop 0:73b89fc74e9f 6 */
Ivop 0:73b89fc74e9f 7
Ivop 0:73b89fc74e9f 8 #ifndef OU_KERNEL_H
Ivop 0:73b89fc74e9f 9 #define OU_KERNEL_H
Ivop 0:73b89fc74e9f 10
Ivop 0:73b89fc74e9f 11 #ifndef NULL
Ivop 0:73b89fc74e9f 12 #define NULL ((void *)0)
Ivop 0:73b89fc74e9f 13 #endif
Ivop 0:73b89fc74e9f 14
Ivop 0:73b89fc74e9f 15 #define OU_VERSION 1
Ivop 0:73b89fc74e9f 16
Ivop 0:73b89fc74e9f 17 #define OU_CONCAT2(x,y) x##y
Ivop 0:73b89fc74e9f 18 #define OU_CONCAT(x,y) OU_CONCAT2(x,y)
Ivop 0:73b89fc74e9f 19
Ivop 0:73b89fc74e9f 20 #define OU_TASK(name) static void name(void) { if(ou_state) goto *ou_state; {
Ivop 0:73b89fc74e9f 21 #define OU_ENDTASK OU_SUSPEND; ou_wait=0; }}
Ivop 0:73b89fc74e9f 22
Ivop 0:73b89fc74e9f 23 #define OU_WAIT(ticks) { ou_wait = ticks; ou_state = &&OU_CONCAT(L,__LINE__); return; } \
Ivop 0:73b89fc74e9f 24 OU_CONCAT(L,__LINE__):
Ivop 0:73b89fc74e9f 25
Ivop 0:73b89fc74e9f 26 #define OU_YIELD do{ OU_WAIT(0); }while(0)
Ivop 0:73b89fc74e9f 27 #define OU_SUSPEND do{ ou_tasks[ou_current_task].suspended = 1; OU_WAIT(0); }while(0)
Ivop 0:73b89fc74e9f 28 #define OU_START(t) do{ ou_tasks[t].suspended = 0; OU_WAIT(0); }while(0)
Ivop 0:73b89fc74e9f 29
Ivop 0:73b89fc74e9f 30 #define OU_GET_TASK_PRIORITY(t) ou_tasks[t].priority
Ivop 0:73b89fc74e9f 31 #define OU_SET_TASK_PRIORITY(t,p) ou_tasks[t].priority = p
Ivop 0:73b89fc74e9f 32
Ivop 0:73b89fc74e9f 33 #define OU_GET_MY_PRIORITY() OU_GET_TASK_PRIORITY(ou_current_task)
Ivop 0:73b89fc74e9f 34 #define OU_SET_MY_PRIORITY(p) OU_SET_TASK_PRIORITY(ou_current_task,p)
Ivop 0:73b89fc74e9f 35
Ivop 0:73b89fc74e9f 36 // Note: Locks only work between tasks, NOT between tasks and interrupt handlers.
Ivop 0:73b89fc74e9f 37 // For that, we need a full-blown mutex
Ivop 0:73b89fc74e9f 38
Ivop 0:73b89fc74e9f 39 #define OU_LOCK(i) while(!i) OU_WAIT(1); i=1
Ivop 0:73b89fc74e9f 40 #define OU_UNLOCK(i) i=0
Ivop 0:73b89fc74e9f 41
Ivop 0:73b89fc74e9f 42 struct ou_task {
Ivop 0:73b89fc74e9f 43 void (*function)(void); // entry point of task
Ivop 0:73b89fc74e9f 44 volatile unsigned priority, // 0 is highest, UINT_MAX-1 is lowest
Ivop 0:73b89fc74e9f 45 suspended, // task is suspended (=1)
Ivop 0:73b89fc74e9f 46 wait; // ticks to wait before running again
Ivop 0:73b89fc74e9f 47 unsigned delayed; // # of times scheduling was delayed
Ivop 0:73b89fc74e9f 48 void *state; // current state within function
Ivop 0:73b89fc74e9f 49 };
Ivop 0:73b89fc74e9f 50
Ivop 0:73b89fc74e9f 51 void ou_update_tasks(void); // called from timer interrupt
Ivop 0:73b89fc74e9f 52 void ou_scheduler(void); // main loop
Ivop 0:73b89fc74e9f 53
Ivop 0:73b89fc74e9f 54 extern struct ou_task ou_tasks[];
Ivop 0:73b89fc74e9f 55 extern void *ou_state;
Ivop 0:73b89fc74e9f 56 extern unsigned ou_wait, ou_current_task, ou_ticks;
Ivop 0:73b89fc74e9f 57 extern const unsigned ou_ntasks;
Ivop 0:73b89fc74e9f 58
Ivop 0:73b89fc74e9f 59 #endif