[uCsimm] RTEC: simple concurrent task system

From: Bernhard Kuhn (kuhn@batian.lpr.e-technik.tu-muenchen.de)
Date: Sat Jan 08 2000 - 00:14:30 EST


Hi!

Now, it is possible to have concurrent rt-tasks with seperated stacks
in uClinux.

In rt_init_app() you just have to call rt_init_task() (and starting
the timer as usual), and within every rt-task, you can call rt_sleep()
to wait until the next timer period occurs.

As the stuff is rather simple, i added the whole
../linux/arch/m68knommu/platform/68328/rt_application.c
so those, who are interressted can have a look at it.

The next step is a full priority scheduler :-)
(but even then, there are still many things missing: FIFOs and
convenient shared memory mechanisms)

BTW: Jeff will supply me with a uCsimm, so that i can play with real
hardware :-)

/* ../linux/arch/m68knommu/platform/68328/rt_application.c , bkuhn/GPL */

#include <asm/system.h>
#include <asm/MC68328.h>

extern int rt_request_irq(unsigned int irq, void (*handler)(void));
extern void rt_free_irq(unsigned int irq);
extern void rt_starttimer(int period);

unsigned long fb_data[160][5];

/* ------------ the following should part of the core ------------ */

#define STACKSIZE 4000

struct rttc {
  int stackpointer;
  int stack[STACKSIZE];
};

struct rttc rtlinuxtask;
struct rttc *current_task=&rtlinuxtask;

void rt_switch_to_task(struct rttc *new_task) {
  __asm__ __volatile__ (
    "movem.l %%d0-%%d7/%%a0-%%a6,-(%%sp)\n\t"
    "move.l %#1f,-(%%sp)\n\t"
    "move.l (%0),%%a1\n\t"
    "move.l %%sp,(%%a1)\n\t"
    "move.l %1,(%0)\n\t"
    "move.l %1,%%a1\n\t"
    "move.l (%%a1),%%sp\n\t"
    "rts\n\t"
"1: movem.l (%%sp)+,%%d0-%%d7/%%a0-%%a6\n\t"
    : : "a" (&current_task) , "d" (new_task) : "%a1", "memory");
};

#define MAX_TASKS 16
struct rttc *tasklist[MAX_TASKS];
int tasks=0;

void rt_init_task(struct rttc *task,void (*code)(void)) {
  task->stack[STACKSIZE-16]=(int) code;
  task->stackpointer=(int) &(task->stack[STACKSIZE-16]);
  tasklist[tasks++]=task;
};

void rt_wakeup_tasks() {
  int i;
  for(i=0;i<tasks;i++) {
    rt_switch_to_task(tasklist[i]);
  };
};

void rt_sleep() {
  rt_switch_to_task(&rtlinuxtask);
};

/* ------- the demo begins here --------- */

struct rttc task1,task2,task3;

void task1_code(void) {
  while(1) {
    fb_data[10][0]--;
    rt_sleep();
  };
};

void task2_code(void) {
  while(1) {
    fb_data[10][2]++;
    rt_sleep();
  };
};

void task3_code(void) {
  while(1) {
    fb_data[10][4]-=5;
    rt_sleep();
  };
};

/* rt-handler for timer1 */
void rt_timer_demo(void) {

  /* start the concurrent tasks */
  rt_wakeup_tasks();

  /* don't forget to reset the pending interrupt! */
  TSTAT1 &= 0;
};

/* rt-handler for pen */
void rt_pen_demo(void) {

  /* just do something */
  fb_data[20][2]--;

  /* pen-irq doesn't seem to be resetable ? */

};

void rt_init_app(void) {

  /* set LCD-Display output area */
  LSSA = fb_data;

  /* init the concurrent tasks */
  rt_init_task(&task1,task1_code);
  rt_init_task(&task2,task2_code);
  rt_init_task(&task3,task3_code);
 
  /* start timer1 and request handler */
  rt_starttimer(10000);
  rt_request_irq(TMR1_IRQ_NUM,rt_timer_demo);

  /* request handler for pen-interrupt */
  rt_request_irq(PEN_IRQ_NUM,rt_pen_demo);
 
};
This message resent by the ucsimm@uclinux.com list server http://www.uClinux.com/



This archive was generated by hypermail 2b30 : Sun Apr 07 2002 - 00:01:33 EST