[rtl] RTEC-0.3: added software interrupts
RTEC-0.3 - a concurrent realtime task system 1. Changes to RTEC-0.2: 2. Introduction 3. API description 4. Download 5. Installation 1. Changes to RTEC-0.2: === o Timing Bugfix o Added soft-interrupt support o rearranged the core (rt_core.c) o created a better understandable demo (rt_application.c) o more convenient "API" 2. Introduction === RTEC is a try to port RTLinux to uClinux. Actually, there is no priority task-scheduler, but you can have up to 16 concurrent periodic tasks (only limited by #define) running at a desired periodizity. Every task has it's own stack, currently limited to 16KB (hardcoded). This is the basis for a scheduler. Additionaly, you can send an emulated interrupt to the standard linux kernel. This is the basis for a FIFO-handler (dev/rtf*). Currently, the system is limited to MC68328. 3. API decription = There are only a view functions that are interessting for the user: RT-Task handling: - void rt_task_create(RTTASK *task,void (*code)(void),int add_to_list); void rt_task_sleep(void); void rt_start_concurrent_task_system(hrtime_t period); void rt_switch_to_task(RTTASK *new_task); RT-Interrupt handling: -- int rt_request_irq(unsigned int irq, void (*handler)(void)); void rt_free_irq(unsigned int irq); Soft-Interrupt handling: void rt_pend_soft_irq(irq) void rt_reset_soft_irq(irq) Have a look at the Demo-Application to understand for what these functions are used for: /* ../linux/arch/m68knommu/platform/68328/rt_application.c */ #include asm/system.h #include asm/MC68328.h #include linux/rtl.h #include linux/sched.h #include asm/irq.h unsigned long fb_data[160][5]; /* soft interrupt emulation - */ #define MY_SOFT_RT_IRQ_NUM 31 int my_soft_rt_irq_handler(int vec, struct pt_regs *fp) { printk("soft irq occured\n"); rt_reset_soft_irq(MY_SOFT_RT_IRQ_NUM); return 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 ? */ /* send software interrupt to linux kernel */ rt_pend_soft_irq(MY_SOFT_RT_IRQ_NUM); }; /* - concurrent task system demo --- */ RTTASK rt_listed_task1,rt_listed_task2; RTTASK rt_circular_task1,rt_circular_task2; /* this two "listed" tasks will be called every 2 ms automaticaly */ void rt_listed_task1_code(void) { while(1) { fb_data[5][0]--; rt_task_sleep(); }; }; void rt_listed_task2_code(void) { while(1) { rt_switch_to_task(rt_circular_task1); }; }; /* circular_task1 will be started by rt_listed_task2. circular_task2 will be started by rt_circular_task1. circular_task2 will go back to rtlinuxtask */ void rt_circular_task1_code(void) { while(1) { fb_data[5][2]++; rt_switch_to_task(rt_circular_task2); }; }; void rt_circular_task2_code(void) { while(1) { fb_data[5][4]-=5000; rt_switch_to_task(rtlinuxtask); }; }; /* -- init - */ void rt_init_app(void) { /* set LCD-Display output area */ LSSA = fb_data; /* request handler for pen-interrupt */ rt_request_irq(PEN_IRQ_NUM,rt_pen_demo); rt_task_create(rt_listed_task1,rt_listed_task1_code,1); rt_task_create(rt_listed_task2,rt_listed_task2_code,1); rt_task_create(rt_circular_task1,rt_circular_task1_code,0); rt_task_create(rt_circular_task2,rt_circular_task2_code,0); request_irq(IRQ_MACHSPEC | MY_SOFT_RT_IRQ_NUM, my_soft_rt_irq_handler, IRQ_FLG_LOCK, "my_irq", NULL); /* start timer1 and request handler */ rt_start_concurrent_task_system(200); /* 2ms */ }; 4. Download === This is a patch against uClinux-2.0.38.1pre1: wget http://www.rcs.ei.tum.de/~kuhn/uclinux/uClinux-2.0.38.1pre1_rt-0.3.diff.gz 5. Installation === Just unpack a clean linux-2.0.38 and patch it with uClinux-2.0.38.1pre1 and then apply the patch above. For a more detailed installation instruction, refer to the readme-file of rtec-0.1: wget http://www.rcs.ei.tum.de/~kuhn/uclinux/rtec-0.1.txt --- [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/
[rtl] jitter test
Hi ! Since I have reproduced the jitter measurement with identical results on four i486 platforms in the meanwhile running 30min , I guess its worth checking if there realy is a problem or if this is a sideeffect of something I am doing/running here with my boxes. I don't know if there realy is such a delay or if this delay is only "measured" in any case this would be a problem. the code is ugly , but it works for me , I now put the cals in a loop wich makes the measured execution time a littl higher , but it did not change the results. the rt_process.c file is thought as replacement of the examples/measurement/rt_process.c , it uses the rtl.mk file that is located in that directory to find your rtl stuff. modifications are in common.h/monitor.c/Makfile and rt_process.c. I would be especialy interested in results from i486 platforms. to get the results I did the folowing: diddl: cat /proc/interrupts intr ; ./monitro jitt ; cat /proc/interrupt intr so I get the interrup count for the interrupts that occured during the test and the "jitter" in two files. to sort things out I simply do diddl: grep "run1" jitt | cut -f 3 -d ":" | sort | uniq --count this gives you the "histogram" of jitter events for the run1 (delay between first and second cal) . thx nmg default: all include rtl.mk histplot: histplot.c $(CC) -o histplot histplot.c monitor: monitor.c $(CC) ${INCLUDE} -Wall -O2 -o monitor monitor.c rt_process.o: rt_process.c $(CC) ${INCLUDE} ${CFLAGS} -c rt_process.c -o rt_process.o all: monitor histplot rt_process.o #test, remove any modules, load new ones and run app test: all @echo "This tests scheduling accuracy" @echo "by running a single periodic task using the one" @echo "shot schedular and testing checking times when it is called" @echo "First we remove any existing rtl-modules" @echo "You may see error warnings from \"make\" - ignore them" @echo "Type return to continue" @read junk -rmmod hello -rmmod sound -rmmod rt_process -rmmod frank_module (cd ../../; ./rmrtl) @echo "Now insert the fifo and scheduler" @echo "Type return to continue" @read junk (cd ../../; ./insrtl) @echo "Now start the real-time tasks module" @echo "Type return to continue" @read junk @insmod rt_process.o @echo "Now starting the application" @echo "The \"min\" is the smallest timing error" @echo "A negative value means that the task ran too early" @echo "The \"max\" is the largest timing error" @./monitor stop_test: -rmmod rt_process -rmmod rtl_fifo -rmmod rtl_sched -rmmod rtl_time clean: rm -f *.o monitor histplot /* * RTL scheduling accuracy measuring example * * (C) Michael Barabanov, 1997 * (C) FSMLabs 1999. [EMAIL PROTECTED] * Released under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991 * Any use of this code must include this notice. */ #include rtl.h #include rtl_fifo.h #include time.h #include rtl_sched.h #include rtl_sync.h #include pthread.h #include unistd.h #include rtl_debug.h #include errno.h #include "common.h" int ntests=500; int period=100; int mode=0; int fifo_size=4000; int advance=0; MODULE_PARM(period,"i"); MODULE_PARM(ntests,"i"); MODULE_PARM(mode,"i"); MODULE_PARM(advance,"i"); pthread_t thread; int fd_fifo; void *thread_code(void *param) { int jittvec_idx; hrtime_t expected; hrtime_t diff[VECSIZE]; hrtime_t end[VECSIZE+1]; hrtime_t min_diff[VECSIZE]; hrtime_t max_diff[VECSIZE]; struct sample samp; int i; int cnt = 0; DECLARE_CPUID(cpu_id); rtl_printf ("Measurement task starts on CPU %d\n", cpu_id); if (mode) { int ret = rtl_setclockmode (rtl_getschedclock(), RTL_CLOCK_MODE_PERIODIC, period); if (ret != 0) { conpr("Setting periodic mode failed\n"); mode = 0; } } if (mode) { struct timespec resolution; /* need to round up the period; should this be done * in pthread_make_periodic? */ clock_getres (rtl_getschedclock(), resolution); period = timespec_to_ns (resolution); } else { rtl_setclockmode (rtl_getschedclock(), RTL_CLOCK_MODE_ONESHOT, 0); } expected = clock_gethrtime(rtl_getschedclock()) + 2 * period; if (advance) { pthread_make_periodic_np (pthread_self(), expected - advance, period); } else { pthread_make_periodic_np (pthread_self(), expected, period); } fd_fifo = open("/dev/rtf0", O_NONBLOCK); if (fd_fifo 0) { rtl_printf("/dev/rtf0 open