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" (¤t_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); }; --- [rtl] --- To unsubscribe: echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED] ---- For more information on Real-Time Linux see: http://www.rtlinux.org/~rtlinux/