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=1000000; 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 returned %d\n", fd_fifo); return (void *) -1; } if (advance) { rtl_stop_interrupts(); /* Be careful with this! The task won't be preempted by anything else. This is probably only appropriate for small high-priority tasks. */ } do { for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){ min_diff[jittvec_idx] = 2000000000; max_diff[jittvec_idx] = -2000000000; } for (i = 0; i < ntests; i++) { ++cnt; pthread_wait_np(); for(jittvec_idx=0;jittvec_idx<=VECSIZE;jittvec_idx++){ end[jittvec_idx] = clock_gethrtime(CLOCK_UST); } for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){ diff[jittvec_idx] = end[jittvec_idx+1]-end[jittvec_idx]; } for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){ if (diff[jittvec_idx] < min_diff[jittvec_idx]) { min_diff[jittvec_idx] = diff[jittvec_idx]; } if (diff[jittvec_idx] > max_diff[jittvec_idx]) { max_diff[jittvec_idx] = diff[jittvec_idx]; } } } for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){ samp.run[jittvec_idx] = min_diff[jittvec_idx]; samp.jitt[jittvec_idx] = (max_diff[jittvec_idx]-min_diff[jittvec_idx]); } write (fd_fifo, &samp, sizeof(samp)); } while (1); return 0; } int init_module(void) { pthread_attr_t attr; struct sched_param sched_param; int thread_status; int fifo_status; rtf_destroy(0); fifo_status = rtf_create(0, fifo_size); if (fifo_status) { rtl_printf("RTL measurement test fail. fifo_status=%d\n",fifo_status); return -1; } rtl_printf("RTL measurement module on CPU %d\n",rtl_getcpuid()); pthread_attr_init (&attr); pthread_attr_setcpu_np(&attr, 0 /*!rtl_getcpuid()*/); sched_param.sched_priority = 1; pthread_attr_setschedparam (&attr, &sched_param); rtl_printf("About to thread create\n"); thread_status = pthread_create (&thread, &attr, thread_code, (void *)1); if (thread_status != 0) { rtl_printf("failed to create RT-thread; errno=\n", errno); return -1; } else { /* rtl_printf("created RT-thread\n"); */ } return 0; } void cleanup_module(void) { rtl_printf ("Removing module on CPU %d\n", rtl_getcpuid()); pthread_delete_np (thread); close(fd_fifo); /* should be: pthread_cancel(thread); pthread_join(thread); */ /* or: rtl_pthread_kill_other_threads(); */ rtf_destroy(0); }
/* * RTL scheduling accuracy measuring example, user program * * (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 <stdio.h> #include <errno.h> #include <sys/time.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <rtl_fifo.h> #include "common.h" int main() { int fd0; int n; int jittvec_idx; struct sample samp; if ((fd0 = open("/dev/rtf0", O_RDONLY)) < 0) { fprintf(stderr, "Error opening /dev/rtf0\n"); exit(1); } while (1) { n = read(fd0, &samp, sizeof(samp)); for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){ printf("run%d:\t %8d, jitt: %8d\n",jittvec_idx,(int) samp.run[jittvec_idx], (int) samp.jitt[jittvec_idx]); } fflush(stdout); } return 0; }
#define LPT_PORT 0x378 #define LPT_IRQ 7 #define RTC_IRQ 8 #define VECSIZE 20 #include <rtl_time.h> struct sample { hrtime_t run[VECSIZE]; hrtime_t jitt[VECSIZE]; };