Skip to content

How to Write A Simple Micro Kernel

Intro

Hello, everybody.  You are here to see how to write a simple micro kernel for ARMs.  Last year, I wrote a very easy micro kernel which named Totoro, spending about two months in my spare time.  I remember that i was very excited when the kernel works.  Maybe, like Linus Torvalds when he got the Linux running around.  You can get more at Linux – a free unix-386 kernel .

I am very happy about this Project. Now, let’s start!

Thread

Fisrtly, we need to understand the concept which named ‘thread’. A thread is combined with task status, task data, it can pause, resume, stop. The main part of this is called ‘context’. In this micro kernel, a thread, also as known TCB, is consist of SOC’s registers’s value, like r0, r1, r2, … , pc, lr, sp and so on. The different part of threads is that has it’s own procedure.

Context

As we have mentioned above, context is the most important part of thread.  Context keeps the states of thread in RAM, and these states will be recovery by scheduler.  Let’s give it a simple picture:

Simple Scheduler

 

Basic Data Structures

include/totoro/taskq.h

struct tasklist {
	struct ttr_tcb *tcb;
	struct tasklist *next;
};
static struct tasklist *migrate(struct ttr_tcb *tcb,
                        struct tasklist **src,
                        struct tasklist **dst)
static void insert(struct tasklist *node, struct tasklist **list);
extern ttr_err_t task_enqueue(struct ttr_tcb *tcb);
extern struct ttr_tcb *task_next(void);
extern void task_init(void);

 

Task Structure

include/totoro/taskq.h

/* definition for Task(Thread) Control Block */
struct ttr_tcb
{
	/* stack pointer */
	volatile void *sp;
	/* current state of the thread */
	uint8_t stat;
	/* priority of the thread */
	uint8_t prior;
	/* thread's stack size */
	uint32_t stack_size;
	/* thread's stack */
	void *stack;
	/* thread function */
	void (*ttr_thread)(void);
};

 

Task Priorities

include/totoro/taskq.h

#define TASK_HIGHEST_PRIORITY  ( 0 )
#define TASK_LOWEST_PRIORITY   (255)
#define TASK_DEFAULT_PRIORITY  ( 1 )

 

Task Status

include/totoro/taskq.h

#define TASK_SUSPENDED  ( 0 )
#define TASK_READY      ( 1 )
#define TASK_RUNNING    ( 2 )

 

Memag of Task Node

kernel/taskq.c

#define MALLOC_TASK_NODE(node, _tcb) \
	((node = (struct tasklist *)malloc(sizeof(struct tasklist))), \
	(!!node ? (node->tcb = _tcb, TTR_ERR_OK) : TTR_ERR_MEM))

#define DELETE_TASK_NODE(node) \
	if (node) { \
		free(node); \
		node->tcb = NULL; \
		node = NULL; \
	}

 

Context switch

arch/cortex-m0/gcc/port.S

    cpsid     i
    mrs       r0, psp
    subs      r0, #32
    stmia     r0!, {r4 - r11}
    subs      r0, #32

    ldr       r2, =ttr_running_task         
    ldr       r1, [r2]
    str       r0, [r1]

    ldr       r1, =ttr_running_task
    ldr       r2, =ttr_next_task
    ldr       r3, [r2]
    str       r3, [r1]

    ldr       r2, =ttr_next_task                
    ldr       r1, [r2]
    ldr       r0, [r1]

    ldmia     r0!, {r4 - r11}
    msr       psp, r0

    ldr       r0, =0xfffffffd
    cpsie     i
    bx        r0

 

Driver Interface

drivers/clock, drivers/gpio, drivers/serial

 

Semaphore

include/totoro/sem.h

extern int sem_signal(sem_t *sem);
extern int sem_wait(sem_t *sem, uint32_t timeout);

 

Mutex

include/totoro/simplelock.h

#define simplelock_get()
#define simplelock_put()

 

Softirq

include/totoro/softirq.h

kernel/timer.c

 

3 Test Cases

test/ab.c

test/sem.c

test/kt.c

Post a Comment

Your email is never published nor shared. Required fields are marked *