⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calibrate.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
字号:
/* * Copyright (C) 2003 Paolo Mantegazza <mantegazza@aero.polimi.it> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. */#include <float.h>#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <signal.h>#include <string.h>#include <sys/mman.h>#include <sys/io.h>#include <getopt.h>#include <pthread.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <termio.h>#include <sys/poll.h>#include <sys/wait.h>#include <fcntl.h>#include <unistd.h>#include <ctype.h>#include <time.h>#include <signal.h>#include <asm/rtai_srq.h>#include <rtai_fifos.h>#include "calibrate.h"struct option options[] = {    { "help",       0, 0, 'h' },    { "r8254",      0, 0, 'r' },    { "kernel",     0, 0, 'k' },#ifdef CONFIG_RTAI_SCHED_LXRT    { "user",       0, 0, 'u' },#endif    { "period",     1, 0, 'p' },    { "time",       1, 0, 't' },    { "cpu",        0, 0, 'c' },    { "apic",       0, 0, 'a' },    { "both",       0, 0, 'b' },    { "scope",      1, 0, 's' },    { "interrupt",  0, 0, 'i' },    { NULL,         0, 0,  0 }};void print_usage(void){    fputs(	("\n*** i386 calibrations ***\n"	 "\n"	 "OPTIONS:\n"	 "  -h, --help\n"	 "      print usage\n"	 "  -r, --r8254\n"	 "      calibrate 8254 oneshot programming type\n"	 "  -k, --kernel\n"	 "      oneshot latency calibrated for scheduling kernel space tasks\n"#ifdef CONFIG_RTAI_SCHED_LXRT	 "  -u, --user\n"	 "      oneshot latency calibrated for scheduling user space tasks\n"#endif	 "  -p <period (us)>, --period <period (us)>\n"	 "      the period of the underlying hard real time task/intr, default 100 (us)\n"	 "  -t <duration (s)>, --time <duration (s)>\n"	 "      set the duration of the requested calibration, default 5 (s)\n"	 "  -c, --cpufreq\n"	 "      calibrate cpu frequency\n"	 "  -a, --apic\n"	 "      calibrate apic frequency\n"	 "  -b, --both\n"	 "      calibrate both apic and cpu frequency\n"	 "  -i, --interrupt\n"	 "      check worst case interrupt locking/contention on your PC\n"	 "  -s<y/n>, --scope<y/n>\n"	 "      toggle parport bit to monitor scheduling on a scope, default y(es)\n"	 "\n")	, stderr);}static void endme(int dummy) { }static void unload_kernel_helper (void){    char modunload[1024];    snprintf(modunload,sizeof(modunload),"/sbin/rmmod %s >/dev/null 2>&1",KERNEL_HELPER_PATH);    system(modunload);}int main(int argc, char *argv[]){	int srq, fifo, command, commands[20], ncommands, c, option_index, i;	struct params_t params;	char str[80], nm[RTF_NAMELEN+1], modload[1024];	unsigned long period = 100, duration = 5, parport = 'y';	unsigned long args[MAXARGS];	struct pollfd polls[2] = { { 0, POLLIN }, { 0, POLLIN } };	option_index = ncommands = 0;	while (1) {		if ((c = getopt_long(argc, argv, "hrkucabip:t:s:", options, &option_index)) == -1) {			break;		}		switch(c) {			case 'h': {				print_usage();				exit(0);			}			case 'r':#ifdef CONFIG_RTAI_SCHED_LXRT			case 'u':#endif			case 'c':			case 'b':			case 'a':			case 'i':			case 'k': {				commands[ncommands++] = c;				break;			}			case 'p': {				period = atoi(optarg);				break;			}			case 't': {				duration = atoi(optarg);				break;			}			case 's': {				parport = optarg[0] == 'y' ? 'y' : 'n';				break;			}		}	}	if (ncommands <= 0) {		printf("\n*** NOTHING TO BE DONE ***\n");		exit(0);	}	atexit(&unload_kernel_helper);	snprintf(modload,sizeof(modload),"/sbin/insmod %s >/dev/null 2>&1",KERNEL_HELPER_PATH);	system(modload);	signal(SIGINT, endme);	srq = rtai_open_srq(CALSRQ);	if ((fifo = open(rtf_getfifobyminor(0,nm,sizeof(nm)), O_RDONLY)) < 0) {		printf("Error opening %s\n",nm);		exit(1);	}	polls[1].fd = fifo;	args[0] = GET_PARAMS;	rtai_srq(srq, (unsigned int)args);	read(fifo, &params, sizeof(params));	printf("\n*** NUMBER OF REQUESTS: %d. ***\n", ncommands);	for (i = 0; i < ncommands; i++) {		switch (command = commands[i]) {			case 'r': {				args[0] = CAL_8254;			 	printf("\n*** '#define SETUP_TIME_8254 %lu', IN USE %lu ***\n\n", (unsigned long) rtai_srq(srq, (unsigned int)args), params.setup_time_8254);				break;			}			case 'k': {				int average;				args[0] = KLATENCY;				args[1] = period;				args[2] = duration;				printf("\n*** KERNEL SPACE LATENCY CALIBRATION, wait %lu seconds for it ... ***\n", args[2]);				args[2] = (1000000*args[2])/args[1];				args[1] *= 1000;				rtai_srq(srq, (unsigned int)args);				read(fifo, &average, sizeof(average));				average /= (int)args[2];			        if (params.mp) {			        	printf("\n*** '#define LATENCY_APIC %d' (IN USE %lu)\n\n", (int)params.latency_apic + average, params.latency_apic);				} else {					printf("\n*** '#define LATENCY_8254 %d' (IN USE %lu)\n\n", (int)params.latency_8254 + average, params.latency_8254);				}				args[0] = END_KLATENCY;				rtai_srq(srq, (unsigned int)args);				break;			}			case 'u': {				int pid, average;				args[1] = period;				args[2] = duration;				printf("\n*** USER SPACE LATENCY CALIBRATION, wait %lu seconds for it ... ***\n", args[2]);				args[2] = (1000000*args[2])/args[1];				args[1] *= 1000;				sprintf(str, "%lu", args[1]);				sprintf(str + sizeof(str)/2, "%lu", args[2]);				pid = fork();				if (!pid) {					execl(USER_HELPER_PATH, USER_HELPER_PATH, str, str + sizeof(str)/2, NULL);					_exit(1);				}				read(fifo, &average, sizeof(average));				waitpid(pid, 0, 0);				if (kill(pid,0) < 0)				    {				    printf("\n*** Cannot execute calibration helper %s -- aborting\n",USER_HELPER_PATH);				    exit(1);				    }				average /= (int)args[2];			        if (params.mp) {			        	printf("\n*** '#define LATENCY_APIC %d' (IN USE %lu)\n\n", (int)params.latency_apic + average, params.latency_apic);				} else {					printf("\n*** '#define LATENCY_8254 %d' (IN USE %lu)\n\n", (int)params.latency_8254 + average, params.latency_8254);				}				break;			}			case 'a': 				if (!params.mp) {					printf("*** APIC FREQUENCY CALIBRATION NOT AVAILABLE UNDER UP ***\n");						break;					}			case 'b':			case 'c': {				unsigned long time, cpu_freq = 0, apic_freq = 0;				struct times_t times;				args[0] = FREQ_CAL;				args[1] = duration;				printf("\n->>> FREQ CALIB (PRINTING EVERY %lu SECONDS, press enter to end calibrating) <<<-\n\n", args[1]);				rtai_srq(srq, (unsigned int)args);				time = 0;				while (1) {					time += args[1];					if (poll(polls, 2, 1000*duration) > 0 &&polls[0].revents) {						getchar();						args[0] = END_FREQ_CAL;						rtai_srq(srq, (unsigned int)args);						if (command == 'c' || command == 'b') {				 			printf("\n*** '#define CPU_FREQ %lu', IN USE %lu ***\n\n", cpu_freq, params.cpu_freq);						}						if (params.mp && (command == 'a' || command == 'b')) {			 				printf("\n*** '#define APIC_FREQ %lu', IN USE %lu ***\n\n", apic_freq, params.freq_apic);						}						break;					}					read(fifo, &times, sizeof(times));					if (command == 'c' || command == 'b') {						cpu_freq = (((double)times.cpu_time)*params.clock_tick_rate)/(((double)times.intrs)*params.latch) + 0.49999999999999999;						printf("\n->>> MEASURED CPU_FREQ: %lu (Hz) [%lu (s)], IN USE %lu (Hz) <<<-\n", cpu_freq, time, params.cpu_freq);					}					if (params.mp && (command == 'a' || command == 'b')) {						apic_freq = (((double)times.apic_time)*params.clock_tick_rate)/(((double)times.intrs)*params.latch) + 0.49999999999999999;						printf("\n->>> MEASURED APIC_FREQ: %lu (Hz) [%lu (s)], IN USE %lu (Hz) <<<-\n", apic_freq, time, params.freq_apic);					}				}				break;			}			case 'i': {				time_t timestamp;				struct tm *tm_timestamp;				args[0] = BUS_CHECK;				args[1] = period;				args[2] = 1;				args[3] = parport;				printf("\n->>> INTERRUPT LATENCY CHECK (press enter to end check) <<<-\n\n");				args[1] *= 1000;				args[2] *= 1000;				rtai_srq(srq, (unsigned int)args);				while (1) {					int maxj;					if (poll(polls, 2, 100) > 0) {						if (polls[0].revents) {							getchar();							args[0] = END_BUS_CHECK;							rtai_srq(srq, (unsigned int)args);							break;						}						read(fifo, &maxj, sizeof(maxj));						time(&timestamp);						tm_timestamp = localtime(&timestamp);						printf("%04d/%02d/%0d-%02d:%02d:%02d -> ", tm_timestamp->tm_year+1900, tm_timestamp->tm_mon+1, tm_timestamp->tm_mday, tm_timestamp->tm_hour, tm_timestamp->tm_min, tm_timestamp->tm_sec);						printf("%d.%-3d (us)\n", maxj/1000, maxj%1000);					}				}				break;			}		}	}	exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -