freebsd-skq/tools/test/ppsapi/ppsapitest.c
phk 1ea153590e Add an option to write collected data to file in binary format. This
is very useful for collecting test-data for trial runs.
2004-03-10 20:30:19 +00:00

190 lines
4.1 KiB
C

/*-
* Copyright (c) 1998-2003 Poul-Henning Kamp
*
* Please see src/share/examples/etc/bsd-style-copyright.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <sys/timepps.h>
static int aflag, Aflag, cflag, Cflag, eflag, uflag, vflag;
static void
Chew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc)
{
printf("%jd .%09ld %u", (intmax_t)tsa->tv_sec, tsa->tv_nsec, sa);
printf(" %jd .%09ld %u\n", (intmax_t)tsc->tv_sec, tsc->tv_nsec, sc);
if (uflag)
fflush(stdout);
}
int
main(int argc, char **argv)
{
int fd;
FILE *fdo;
pps_info_t pi;
pps_params_t pp;
pps_handle_t ph;
int i, mode;
u_int olda, oldc;
struct timespec to;
char const *ofn;
ofn = NULL;
while ((i = getopt(argc, argv, "aAbBcCeo:uv")) != -1) {
switch (i) {
case 'a': aflag = 1; break;
case 'A': Aflag = 1; break;
case 'b': aflag = 1; cflag = 1; break;
case 'B': Aflag = 1; Cflag = 1; break;
case 'c': cflag = 1; break;
case 'C': Cflag = 1; break;
case 'e': eflag = 1; break;
case 'o': ofn = optarg; break;
case 'u': uflag = 1; break;
case 'v': vflag = 1; break;
case '?':
default:
fprintf(stderr,
"Usage: ppsapitest [-aAcC] device\n");
exit (1);
}
}
if (ofn != NULL) {
fdo = fopen(ofn, "w");
if (fdo == NULL)
err(1, "Cannot open %s", ofn);
} else {
fdo = NULL;
}
argc -= optind;
argv += optind;
if (argc > 0) {
fd = open(argv[0], O_RDONLY);
if (fd < 0)
err(1, argv[0]);
} else {
fd = 0;
}
i = time_pps_create(fd, &ph);
if (i < 0)
err(1, "time_pps_create");
i = time_pps_getcap(ph, &mode);
if (i < 0)
err(1, "time_pps_getcap");
if (vflag) {
fprintf(stderr, "Supported modebits:");
if (mode & PPS_CAPTUREASSERT)
fprintf(stderr, " CAPTUREASSERT");
if (mode & PPS_CAPTURECLEAR)
fprintf(stderr, " CAPTURECLEAR");
if (mode & PPS_OFFSETASSERT)
fprintf(stderr, " OFFSETASSERT");
if (mode & PPS_OFFSETCLEAR)
fprintf(stderr, " OFFSETCLEAR");
if (mode & PPS_ECHOASSERT)
fprintf(stderr, " ECHOASSERT");
if (mode & PPS_ECHOCLEAR)
fprintf(stderr, " ECHOCLEAR");
if (mode & PPS_CANWAIT)
fprintf(stderr, " CANWAIT");
if (mode & PPS_CANPOLL)
fprintf(stderr, " CANPOLL");
if (mode & PPS_TSFMT_TSPEC)
fprintf(stderr, " TSPEC");
if (mode & PPS_TSFMT_NTPFP)
fprintf(stderr, " NTPFP");
fprintf(stderr, "\n");
}
if (!aflag && !cflag) {
if (mode & PPS_CAPTUREASSERT)
aflag = 1;
if (mode & PPS_CAPTURECLEAR)
cflag = 1;
}
if (!Aflag && !Cflag) {
Aflag = aflag;
Cflag = cflag;
}
if (Cflag && !(mode & PPS_CAPTURECLEAR))
errx(1, "-C but cannot capture on clear flank");
if (Aflag && !(mode & PPS_CAPTUREASSERT))
errx(1, "-A but cannot capture on assert flank");
i = time_pps_getparams(ph, &pp);
if (i < 0)
err(1, "time_pps_getparams():");
if (aflag)
pp.mode |= PPS_CAPTUREASSERT;
if (cflag)
pp.mode |= PPS_CAPTURECLEAR;
if (eflag & aflag)
pp.mode |= PPS_ECHOASSERT;
if (eflag & cflag)
pp.mode |= PPS_ECHOCLEAR;
if (!(pp.mode & PPS_TSFMT_TSPEC))
pp.mode |= PPS_TSFMT_TSPEC;
i = time_pps_setparams(ph, &pp);
if (i < 0) {
err(1, "time_pps_setparams(mode %x):", pp.mode);
}
/*
* Pick up first event outside the loop in order to not
* get something ancient into the outfile.
*/
to.tv_nsec = 0;
to.tv_sec = 0;
i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
if (i < 0)
err(1, "time_pps_fetch()");
olda = pi.assert_sequence;
oldc = pi.clear_sequence;
while (1) {
to.tv_nsec = 0;
to.tv_sec = 0;
i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
if (i < 0)
err(1, "time_pps_fetch()");
if (oldc != pi.clear_sequence && Cflag)
;
else if (olda != pi.assert_sequence && Aflag)
;
else {
usleep(10000);
continue;
}
if (fdo != NULL) {
if (fwrite(&pi, sizeof pi, 1, fdo) != 1)
err(1, "Write error on %s", ofn);
if (uflag)
fflush(fdo);
}
Chew(&pi.assert_timestamp, &pi.clear_timestamp,
pi.assert_sequence, pi.clear_sequence);
olda = pi.assert_sequence;
oldc = pi.clear_sequence;
}
return(0);
}