Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753354AbYKXQDY (ORCPT ); Mon, 24 Nov 2008 11:03:24 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753334AbYKXQBX (ORCPT ); Mon, 24 Nov 2008 11:01:23 -0500 Received: from 81-174-11-161.static.ngi.it ([81.174.11.161]:58638 "EHLO mail.enneenne.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752923AbYKXQBR (ORCPT ); Mon, 24 Nov 2008 11:01:17 -0500 From: Rodolfo Giometti To: linux-kernel@vger.kernel.org Cc: Andrew Morton , David Woodhouse , Dave Jones , Sam Ravnborg , Greg KH , Randy Dunlap , Kay Sievers , Alan Cox , "H. Peter Anvin" , Ingo Molnar , Rodolfo Giometti Date: Mon, 24 Nov 2008 17:00:45 +0100 Message-Id: <1227542451-31969-4-git-send-email-giometti@linux.it> X-Mailer: git-send-email 1.5.4.3 In-Reply-To: <1227542451-31969-3-git-send-email-giometti@linux.it> References: <> <1227542451-31969-1-git-send-email-giometti@linux.it> <1227542451-31969-2-git-send-email-giometti@linux.it> <1227542451-31969-3-git-send-email-giometti@linux.it> X-SA-Exim-Connect-IP: 192.168.32.254 X-SA-Exim-Mail-From: giometti@enneenne.com Subject: [PATCH 3/9] PPS: documentation programs and examples. X-SA-Exim-Version: 4.2.1 (built Tue, 09 Jan 2007 17:23:22 +0000) X-SA-Exim-Scanned: Yes (on mail.enneenne.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6920 Lines: 296 Here some utilities and examples about the PPS API and the LinuxPPS support. * ppsldisc.c shows how to manage PPS line discipline; * ppstest.c implements an useful testing program, while * ppsfind tries to help the user into finding a specific PPS source by using its name or path. Signed-off-by: Rodolfo Giometti --- Documentation/pps/Makefile | 28 ++++++++ Documentation/pps/ppsfind | 17 +++++ Documentation/pps/ppsldisc.c | 46 +++++++++++++ Documentation/pps/ppstest.c | 151 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 Documentation/pps/Makefile create mode 100644 Documentation/pps/ppsfind create mode 100644 Documentation/pps/ppsldisc.c create mode 100644 Documentation/pps/ppstest.c diff --git a/Documentation/pps/Makefile b/Documentation/pps/Makefile new file mode 100644 index 0000000..9841e6b --- /dev/null +++ b/Documentation/pps/Makefile @@ -0,0 +1,28 @@ +TARGETS = ppstest ppsldisc + +CFLAGS += -Wall -O2 -D_GNU_SOURCE +CFLAGS += -I . +CFLAGS += -ggdb +CFLAGS += -D__N_PPS=$(shell awk '/N_PPS/ {print $$3}' ../../include/linux/tty.h) + +# -- Actions section -- + +.PHONY : all depend dep + +all : .depend $(TARGETS) + +.depend depend dep : + $(CC) $(CFLAGS) -M $(TARGETS:=.c) > .depend + +ifeq (.depend,$(wildcard .depend)) +include .depend +endif + + +# -- Clean section -- + +.PHONY : clean + +clean : + rm -f *.o *~ core .depend + rm -f ${TARGETS} diff --git a/Documentation/pps/ppsfind b/Documentation/pps/ppsfind new file mode 100644 index 0000000..93c0e17 --- /dev/null +++ b/Documentation/pps/ppsfind @@ -0,0 +1,17 @@ +#!/bin/sh + +SYS="/sys/class/pps/" + +if [ $# -lt 1 ] ; then + echo "usage: ppsfind " >&2 + exit 1 +fi + +for d in $(ls $SYS) ; do + if grep $1 $SYS/$d/name >& /dev/null || \ + grep $1 $SYS/$d/path >& /dev/null ; then + echo "$d: name=$(cat $SYS/$d/name) path=$(cat $SYS/$d/path)" + fi +done + +exit 0 diff --git a/Documentation/pps/ppsldisc.c b/Documentation/pps/ppsldisc.c new file mode 100644 index 0000000..036e13b --- /dev/null +++ b/Documentation/pps/ppsldisc.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef N_PPS +#define N_PPS __N_PPS +#endif + +void usage(char *name) +{ + fprintf(stderr, "usage: %s \n", name); + + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) +{ + int fd; + int ldisc = N_PPS; + int ret; + + if (argc < 2) + usage(argv[0]); + + fd = open(argv[1], O_RDWR); + if (fd < 0) { + perror("open"); + exit(EXIT_FAILURE); + } + + ret = ioctl(fd, TIOCSETD, &ldisc); + if (ret < 0) { + perror("ioctl(TIOCSETD)"); + exit(EXIT_FAILURE); + } + + pause(); + + return 0; +} diff --git a/Documentation/pps/ppstest.c b/Documentation/pps/ppstest.c new file mode 100644 index 0000000..d125ffa --- /dev/null +++ b/Documentation/pps/ppstest.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int find_source(char *path, pps_handle_t *handle, int *avail_mode) +{ + pps_params_t params; + int ret; + + printf("trying PPS source \"%s\"\n", path); + + /* Try to find the source by using the supplied "path" name */ + ret = open(path, O_RDWR); + if (ret < 0) { + fprintf(stderr, "unable to open device \"%s\" (%m)\n", path); + return ret; + } + + /* Open the PPS source (and check the file descriptor) */ + ret = time_pps_create(ret, handle); + if (ret < 0) { + fprintf(stderr, "cannot create a PPS source from device " + "\"%s\" (%m)\n", path); + return -1; + } + printf("found PPS source \"%s\"\n", path); + + /* Find out what features are supported */ + ret = time_pps_getcap(*handle, avail_mode); + if (ret < 0) { + fprintf(stderr, "cannot get capabilities (%m)\n"); + return -1; + } + if ((*avail_mode & PPS_CAPTUREASSERT) == 0) { + fprintf(stderr, "cannot CAPTUREASSERT\n"); + return -1; + } + if ((*avail_mode & PPS_OFFSETASSERT) == 0) { + fprintf(stderr, "cannot OFFSETASSERT\n"); + return -1; + } + + /* Capture assert timestamps, and compensate for a 675 nsec + * propagation delay */ + ret = time_pps_getparams(*handle, ¶ms); + if (ret < 0) { + fprintf(stderr, "cannot get parameters (%m)\n"); + return -1; + } + params.assert_offset.tv_sec = 0; + params.assert_offset.tv_nsec = 675; + params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT; + ret = time_pps_setparams(*handle, ¶ms); + if (ret < 0) { + fprintf(stderr, "cannot set parameters (%m)\n"); + return -1; + } + + return 0; +} + +int fetch_source(int i, pps_handle_t *handle, int *avail_mode) +{ + struct timespec timeout; + pps_info_t infobuf; + int ret; + + /* create a zero-valued timeout */ + timeout.tv_sec = 3; + timeout.tv_nsec = 0; + +retry: + if (*avail_mode & PPS_CANWAIT) /* waits for the next event */ + ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf, + &timeout); + else { + sleep(1); + ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf, + &timeout); + } + if (ret < 0) { + if (ret == -EINTR) { + fprintf(stderr, "time_pps_fetch() got a signal!\n"); + goto retry; + } + + fprintf(stderr, "time_pps_fetch() error %d (%m)\n", ret); + return -1; + } + + printf("source %d - " + "assert %ld.%09ld, sequence: %ld - " + "clear %ld.%09ld, sequence: %ld\n", + i, + infobuf.assert_timestamp.tv_sec, + infobuf.assert_timestamp.tv_nsec, + infobuf.assert_sequence, + infobuf.clear_timestamp.tv_sec, + infobuf.clear_timestamp.tv_nsec, infobuf.clear_sequence); + + return 0; +} + +void usage(char *name) +{ + fprintf(stderr, "usage: %s [ ...]\n", name); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) +{ + int num; + pps_handle_t handle[4]; + int avail_mode[4]; + int i = 0; + int ret; + + /* Check the command line */ + if (argc < 2) + usage(argv[0]); + + for (i = 1; i < argc && i <= 4; i++) { + ret = find_source(argv[i], &handle[i - 1], &avail_mode[i - 1]); + if (ret < 0) + exit(EXIT_FAILURE); + } + + num = i - 1; + printf("ok, found %d source(s), now start fetching data...\n", num); + + /* loop, printing the most recent timestamp every second or so */ + while (1) { + for (i = 0; i < num; i++) { + ret = fetch_source(i, &handle[i], &avail_mode[i]); + if (ret < 0 && errno != ETIMEDOUT) + exit(EXIT_FAILURE); + } + } + + for (; i >= 0; i--) + time_pps_destroy(handle[i]); + + return 0; +} -- 1.5.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/