예제 #1
0
int main(void)
{
	RT_TASK *Main_Task;
	long msg;

	if (!(Main_Task = rt_thread_init(nam2num("MNTSK"), 10, 0, SCHED_FIFO, 0xF))) {
		printf("CANNOT INIT MAIN TASK\n");
		exit(1);
	}

	if (!(hard_timer_running = rt_is_hard_timer_running())) {
		start_rt_timer(0);
	}
	barrier = rt_sem_init(nam2num("PREMS"), 4);
	latency_thread = rt_thread_create(latency_fun, NULL, 0);
	fast_thread    = rt_thread_create(fast_fun, NULL, 0);
	slow_thread    = rt_thread_create(slow_fun, NULL, 0);
	start = rt_get_time() + nano2count(200000000);
	rt_sem_wait_barrier(barrier);
	rt_receive(0, &msg);
	end = 1;
	rt_sem_wait_barrier(barrier);
	rt_thread_join(latency_thread);
	rt_thread_join(fast_thread);
	rt_thread_join(slow_thread);
	if (!hard_timer_running) {
		stop_rt_timer();
	}
	rt_sem_delete(barrier);
	rt_thread_delete(Main_Task);
	return 0;
}
예제 #2
0
파일: latency.c 프로젝트: ArcEye/RTAI
static int
__latency_init(void)
{

	/* XXX check option ranges here */

	/* register a proc entry */
#ifdef CONFIG_PROC_FS
	create_proc_read_entry("rtai/latency_calibrate", /* name             */
	                       0,			 /* default mode     */
	                       NULL, 			 /* parent dir       */
			       proc_read, 		 /* function         */
			       NULL			 /* client data      */
	);
#endif

	rtf_create(DEBUG_FIFO, 16000);	/* create a fifo length: 16000 bytes */
	rt_linux_use_fpu(use_fpu);	/* declare if we use the FPU         */

	rt_task_init(			/* create our measuring task         */
			    &thread,	/* poiter to our RT_TASK             */
			    fun,	/* implementation of the task        */
			    0,		/* we could transfer data -> task    */
			    3000,	/* stack size                        */
			    0,		/* priority                          */
			    use_fpu,	/* do we use the FPU?                */
			    0		/* signal? XXX                       */
	);

	rt_set_runnable_on_cpus(	/* select on which CPUs the task is  */
		&thread,		/* allowed to run                    */
		RUN_ON_CPUS
	);

	/* Test if we have to start the timer                                */
	if (start_timer || (start_timer = !rt_is_hard_timer_running())) {
		if (timer_mode) {
			rt_set_periodic_mode();
		} else {
			rt_set_oneshot_mode();
		}
		rt_assign_irq_to_cpu(TIMER_8254_IRQ, TIMER_TO_CPU);
		period_counts = start_rt_timer(nano2count(period));
	} else {
		period_counts = nano2count(period);
	}

	loops = (1000000000*avrgtime)/period;

	/* Calculate the start time for the task. */
	/* We set this to "now plus 10 periods"   */
	expected = rt_get_time() + 10 * period_counts;
	rt_task_make_periodic(&thread, expected, period_counts);
	return 0;
}
예제 #3
0
void latency (void *cookie)
{
    int err, count, nsamples, warmup = 1;
    RTIME expected_tsc, period_tsc, start_ticks;
    RT_TIMER_INFO timer_info;
    RT_QUEUE q;

    rt_queue_create(&q, "queue", 0, 100, 0);

    if (!(hard_timer_running = rt_is_hard_timer_running())) {
	err = rt_timer_start(TM_ONESHOT);
    	if (err)
	   {
	   fprintf(stderr,"latency: cannot start timer, code %d\n",err);
	   return;
	   }
    }

    err = rt_timer_inquire(&timer_info);

    if (err)
	{
	fprintf(stderr,"latency: rt_timer_inquire, code %d\n",err);
	return;
	}

    nsamples = ONE_BILLION / period_ns / 1;
    period_tsc = rt_timer_ns2tsc(period_ns);
    /* start time: one millisecond from now. */
    start_ticks = timer_info.date + rt_timer_ns2ticks(1000000);
    expected_tsc = timer_info.tsc + rt_timer_ns2tsc(1000000);

    err = rt_task_set_periodic(NULL,start_ticks,period_ns);

    if (err)
	{
	fprintf(stderr,"latency: failed to set periodic, code %d\n",err);
	return;
	}

    for (;;)
	{
	long minj = TEN_MILLION, maxj = -TEN_MILLION, dt, sumj;
	long overrun = 0;
	test_loops++;

	for (count = sumj = 0; count < nsamples; count++)
	    {
	    expected_tsc += period_tsc;
	    err = rt_task_wait_period(NULL);

	    if (err)
		{
		if (err != -ETIMEDOUT) {
		    rt_queue_delete(&q);
		    rt_task_delete(NULL); /* Timer stopped. */
		}
		overrun++;
		}

	    dt = (long)(rt_timer_tsc() - expected_tsc);
	    if (dt > maxj) maxj = dt;
	    if (dt < minj) minj = dt;
	    sumj += dt;

	    if (!(finished || warmup) && (do_histogram || do_stats))
		add_histogram(histogram_avg, dt);
	    }

	if(!warmup)
	    {
	    if (!finished && (do_histogram || do_stats))
		{
		add_histogram(histogram_max, maxj);
		add_histogram(histogram_min, minj);
		}

	    minjitter = minj;
	    if(minj < gminjitter)
		gminjitter = minj;

	    maxjitter = maxj;
	    if(maxj > gmaxjitter)
		gmaxjitter = maxj;

	    avgjitter = sumj / nsamples;
	    gavgjitter += avgjitter;
	    goverrun += overrun;
	    rt_sem_v(&display_sem);

	struct smpl_t { long minjitter, avgjitter, maxjitter, overrun; } *smpl;
	smpl = rt_queue_alloc(&q, sizeof(struct smpl_t));
#if 1
	smpl->minjitter = rt_timer_tsc2ns(minj);
	smpl->maxjitter = rt_timer_tsc2ns(maxj);
	smpl->avgjitter = rt_timer_tsc2ns(sumj / nsamples);
	smpl->overrun   = goverrun;
	rt_queue_send(&q, smpl, sizeof(struct smpl_t), TM_NONBLOCK);
#endif

	    }

	if(warmup && test_loops == WARMUP_TIME)
	    {
	    test_loops = 0;
	    warmup = 0;
	    }
	}
}
예제 #4
0
int main(int argc, char *argv[])
{
	int diff;
	int sample;
	long average;
	int min_diff;
	int max_diff;
	int period;
	int i;
	RTIME t, svt;
	RTIME expected, exectime[3];
	MBX *mbx;
	RT_TASK *task, *latchk;
	struct sample { long long min; long long max; int index, ovrn; } samp;
	double s = 0.0, sref;
	long long max = -1000000000, min = 1000000000;

	signal(SIGINT, endme);
	signal(SIGKILL, endme);
	signal(SIGTERM, endme);

 	if (!(mbx = rt_mbx_init(nam2num("LATMBX"), 20*sizeof(samp)))) {
		printf("CANNOT CREATE MAILBOX\n");
		exit(1);
	}

 	if (!(task = rt_task_init_schmod(nam2num("LATCAL"), 0, 0, 0, SCHED_FIFO, 0xF))) {
		printf("CANNOT INIT MASTER LATENCY TASK\n");
		exit(1);
	}

	printf("\n## RTAI latency calibration tool ##\n");
	printf("# period = %i (ns) \n", PERIOD);
	printf("# average time = %i (s)\n", (int)AVRGTIME);
	printf("# use the FPU\n");
	printf("#%sstart the timer\n", argc == 1 ? " " : " do not ");
	printf("# timer_mode is %s\n", TIMER_MODE ? "periodic" : "oneshot");
	printf("\n");

	if (!(hard_timer_running = rt_is_hard_timer_running())) {
		if (TIMER_MODE) {
			rt_set_periodic_mode();
		} else {
			rt_set_oneshot_mode();
		}
		period = start_rt_timer(nano2count(PERIOD));
	} else {
		period = nano2count(PERIOD);
	}

	for(i = 0; i < MAXDIM; i++) {
		a[i] = b[i] = 3.141592;
	}
	sref = dot(a, b, MAXDIM);

	mlockall(MCL_CURRENT | MCL_FUTURE);

	rt_make_hard_real_time();
	expected = rt_get_time() + 200*period;
	rt_task_make_periodic(task, expected, period);
	svt = rt_get_cpu_time_ns();
	i = 0;
	samp.ovrn = 0;
	while (!end) {
		min_diff = 1000000000;
		max_diff = -1000000000;
		average = 0;

		for (sample = 0; sample < SMPLSXAVRG && !end; sample++) {
			expected += period;
			if (!rt_task_wait_period()) {
				if (TIMER_MODE) {
					diff = (int) ((t = rt_get_cpu_time_ns()) - svt - PERIOD);
					svt = t;
				} else {
					diff = (int) count2nano(rt_get_time() - expected);
				}
			} else {
				samp.ovrn++;
				diff = 0;
				if (TIMER_MODE) {
					svt = rt_get_cpu_time_ns();
				}
			}
			outb(i = 1 - i, 0x378);

			if (diff < min_diff) {
				min_diff = diff;
			}
			if (diff > max_diff) {
				max_diff = diff;
			}
			average += diff;
			s = dot(a, b, MAXDIM);
			if (fabs((s - sref)/sref) > 1.0e-15) {
				printf("\nDOT PRODUCT RESULT = %20.16e %20.16e %20.16e\n", s, sref, fabs((s - sref)/sref));
				return 0;
			}
		}
		samp.min = min_diff;
		samp.max = max_diff;
		samp.index = average/SMPLSXAVRG;
#if SOLO
		if (max < samp.max) max = samp.max;
		if (min > samp.min) min = samp.min;
		rt_printk("SOLO * min: %lld/%lld, max: %lld/%lld average: %d (%d) <Hit [RETURN] to stop> *\n", samp.min, min, samp.max, max, samp.index, samp.ovrn);
#else
		rt_mbx_send_if(mbx, &samp, sizeof(samp));
		if ((latchk = rt_get_adr(nam2num("LATCHK"))) && (rt_receive_if(latchk, &average) || end)) {
			rt_return(latchk, average);
			break;
		}
#endif
	}

	while (rt_get_adr(nam2num("LATCHK"))) {
		rt_sleep(nano2count(1000000));
	}
	rt_make_soft_real_time();
	if (!hard_timer_running) {
		stop_rt_timer();
	}
	rt_get_exectime(task, exectime);
	if (exectime[1] && exectime[2]) {
		printf("\n>>> S = %g, EXECTIME = %G\n", s, (double)exectime[0]/(double)(exectime[2] - exectime[1]));
	}
	rt_task_delete(task);
	rt_mbx_delete(mbx);

	return 0;
}
예제 #5
0
파일: latency.c 프로젝트: cjecho/RTAI
int main(int argc, char *argv[])
{
	int sock;
	struct sockaddr_in SPRT_ADDR;
	char buf[200];
	int fd;

	int diff;
	int sample;
	int average;
	int min_diff;
	int max_diff;
	int period;
	int i;
	int cnt;
	RTIME t, svt;
	RTIME expected, exectime[3];
	RT_TASK *task;
	long long max = -1000000000, min = 1000000000;
	struct sample { long long min; long long max; int index, ovrn; } samp;
	double s, sref;

 	if (!(task = rt_task_init_schmod(nam2num("LATCAL"), 0, 0, 0, SCHED_FIFO, 0xF))) {
		printf("CANNOT INIT MASTER LATENCY TASK\n");
		exit(1);
	}

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	bzero(&SPRT_ADDR, sizeof(struct sockaddr_in));
	SPRT_ADDR.sin_family = AF_INET;
	SPRT_ADDR.sin_port = htons(5000);
	SPRT_ADDR.sin_addr.s_addr = inet_addr("127.0.0.1");

	fd = open("echo", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

	printf("\n## RTAI latency calibration tool ##\n");
	printf("# period = %i (ns) \n", PERIOD);
	printf("# average time = %i (s)\n", (int)AVRGTIME);
	printf("# use the FPU\n");
	printf("#%sstart the timer\n", argc == 1 ? " " : " do not ");
	printf("# timer_mode is %s\n", TIMER_MODE ? "periodic" : "oneshot");
	printf("\n");

	rt_sync_async_linux_syscall_server_create(NULL, ASYNC_LINUX_SYSCALL, async_callback, 120);

	if (!(hard_timer_running = rt_is_hard_timer_running())) {
		if (TIMER_MODE) {
			rt_set_periodic_mode();
		} else {
			rt_set_oneshot_mode();
		}
		period = start_rt_timer(nano2count(PERIOD));
	} else {
		period = nano2count(PERIOD);
	}

        for(i = 0; i < MAXDIM; i++) {
                a[i] = b[i] = 3.141592;
        }
	sref = dot(a, b, MAXDIM);
	s = 0.0;

	mlockall(MCL_CURRENT | MCL_FUTURE);

	rt_make_hard_real_time();
	expected = rt_get_time() + 200*period;
	rt_task_make_periodic(task, expected, period);
	svt = rt_get_cpu_time_ns();
	cnt = 0;
	i = 0;
	samp.ovrn = 0;
	while (!end) {
		min_diff = 1000000000;
		max_diff = -1000000000;
		average = 0;

		for (sample = 0; sample < SMPLSXAVRG && !end; sample++) {
			expected += period;
			if (!rt_task_wait_period()) {
				if (TIMER_MODE) {
					diff = (int) ((t = rt_get_cpu_time_ns()) - svt - PERIOD);
					svt = t;
				} else {
					diff = (int) count2nano(rt_get_time() - expected);
				}
			} else {
				samp.ovrn++;
				diff = 0;
				if (TIMER_MODE) {
					svt = rt_get_cpu_time_ns();
				}
			}

			if (diff < min_diff) {
				min_diff = diff;
			}
			if (diff > max_diff) {
				max_diff = diff;
			}
			average += diff;
			s = dot(a, b, MAXDIM);
			if (fabs(s/sref - 1.0) > 1.0e-16) {
				printf("\nDOT PRODUCT RESULT = %lf %lf %lf\n", s, sref, sref - s);
				return 0;
			}
		}
		samp.min = min_diff;
		samp.max = max_diff;
		samp.index = average/SMPLSXAVRG;
		if (max < samp.max) max = samp.max;
		if (min > samp.min) min = samp.min;
		++cnt;
//		printf("* %d - min: %lld/%lld, max: %lld/%lld average: %d <RET to stop> %d *\n", cnt, samp.min, min, samp.max, max, samp.index, samp.ovrn);
		sprintf(buf, "* %d - min: %lld/%lld, max: %lld/%lld average: %d <RET to stop> %d *\n", cnt, samp.min, min, samp.max, max, samp.index, samp.ovrn);
		i = write(STDOUT_FILENO, buf, strlen(buf));
		fdatasync(STDOUT_FILENO);
		i = write(fd, buf, strlen(buf));
		fsync(fd);
		sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&SPRT_ADDR, sizeof(struct sockaddr_in));
	}

	close(sock);
	close(fd);
	rt_make_soft_real_time();
	if (!hard_timer_running) {
		stop_rt_timer();
	}
	rt_get_exectime(task, exectime);
	if (exectime[1] && exectime[2]) {
		printf("\n>>> S = %g, EXECTIME = %G\n", s, (double)exectime[0]/(double)(exectime[2] - exectime[1]));
	}
	rt_task_delete(task);

	return 0;
}
예제 #6
0
int main(int argc, char *argv[])
{
	RT_TASK *task;
	RTIME trp, max = 0, min = 1000000000, avrg = 0;
	int sockfd, ret, hard_timer_running, i;
	struct sockaddr_in local_addr, server_addr;
	struct { long long count; char msg[100]; } msg = { 0LL, "this message was sent using rtnet-rtai." };

	signal(SIGTERM, sigh);
	signal(SIGINT,  sigh);
	signal(SIGHUP,  sigh);

/* Set address structures to zero.  */
	memset(&local_addr, 0, sizeof(struct sockaddr_in));
	memset(&server_addr, 0, sizeof(struct sockaddr_in));

/* Check arguments and set addresses. */
	if (argc == 6) {
		local_addr.sin_family      = AF_INET;
		local_addr.sin_addr.s_addr = INADDR_ANY;
		local_addr.sin_port        = htons(atoi(argv[1]));

		server_addr.sin_family = AF_INET;
		inet_aton(argv[2], &server_addr.sin_addr);
		server_addr.sin_port = htons(atoi(argv[3]));

		NR_TRIPS = atoi(argv[4]);
		PERIOD   = atoi(argv[5])*1000LL;
	} else {
		fprintf(stderr,
				"Usage: "
				"%s <local-port> "
				"<server-ip> <server-port> "
				"<number-of-trips> <sending-period-us>\n",
				argv[0]);
		return 1;
	}

/* Create new socket. */
	sockfd = rt_dev_socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0) {
		printf("Error opening socket: %d\n", sockfd);
		return 1;
	}

/* Link the Linux process to RTAI. */
	if (!(hard_timer_running = rt_is_hard_timer_running())) {
		start_rt_timer(0);
	}
	task = rt_thread_init(nam2num("SMPCLT"), 1, 0, SCHED_OTHER, 0xFF);
	if (task == NULL) {
		rt_dev_close(sockfd);
		printf("CANNOT LINK LINUX SIMPLECLIENT PROCESS TO RTAI\n");
		return 1;
	}

/* Lock allocated memory into RAM. */
	printf("RTnet, simpleclient for RTAI (user space).\n");
	mlockall(MCL_CURRENT|MCL_FUTURE);

/* Switch over to hard realtime mode. */
	rt_make_hard_real_time();

/* Bind socket to local address specified as parameter. */
	ret = rt_dev_bind(sockfd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in));

    /* Specify destination address for socket; needed for rt_socket_send(). */
	rt_dev_connect(sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));

/* Send messages */
	for (i = 1; i <= NR_TRIPS && !end; i++) {
		rt_sleep(nano2count(PERIOD));
		msg.count = i;
		trp = rt_get_time_ns();
		rt_dev_send(sockfd, &msg, sizeof(long long) + strlen(msg.msg) + 1, 0);
		rt_dev_recv(sockfd, &msg, sizeof(msg), 0);
		trp = (msg.count - trp)/1000;
		if (trp < min) min = trp;
		if (i > 3 && trp > max) max = trp;
		avrg += trp;
		printf("Client received: trip time %lld (us), %s\n", trp, msg.msg);
	}
	msg.count = -1;
	rt_dev_send(sockfd, &msg, sizeof(long long) + strlen(msg.msg) + 1, 0);

/* Switch over to soft realtime mode. */
	rt_make_soft_real_time();

/* Close socket, must be in soft-mode because socket was created as non-rt. */
	rt_dev_close(sockfd);

/* Unlink the Linux process from RTAI. */
	if (!hard_timer_running) {
		stop_rt_timer();
	}
	rt_task_delete(task);
	printf("Min trip time %lld, Max trip time %lld, Average trip time %lld\n", min, max, avrg/i);

	return 0;
}