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];
};