A Small Cooperative Multitasking Kernel

Dependencies:   mbed

kernel.h

Committer:
Ivop
Date:
2011-07-24
Revision:
0:73b89fc74e9f

File content as of revision 0:73b89fc74e9f:

/* 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