"Fossies" - the Fresh Open Source Software Archive

Member "PPSkit-2.1.7/gen_pps.c" (10 Feb 1998, 4186 Bytes) of package /linux/misc/old/PPSkit-2.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* $Id: gen_pps.c,v 1.2 1998/02/10 10:55:50 windl Exp $
    2  *  Test program to create a PPS signal on RTS of serial port.
    3  *  Used to test NTP PPS code when no other PPS source is available.
    4  *  Linux 2.0 RTC driver is needed.
    5  *
    6  *  Copyright (C) 1996, Paul Gortmaker.
    7  *  Copyright (C) 1996, 1997, 1998 by Ulrich Windl.
    8  *
    9  *  Released under the GNU General Public License, version 2,
   10  *  included herein by reference.
   11  *
   12  */
   13 
   14 #include <unistd.h>
   15 #include <stdlib.h>
   16 #include <stdio.h>
   17 #include <string.h>
   18 #include <time.h>
   19 #include <sched.h>
   20 #include <sys/mman.h>
   21 #include <linux/mc146818rtc.h>
   22 #include <sys/ioctl.h>
   23 #include <sys/types.h>
   24 #include <fcntl.h>
   25 #include <errno.h>
   26 
   27 static  const char  id[] = "$Id: gen_pps.c,v 1.2 1998/02/10 10:55:50 windl Exp $";
   28 
   29 static  int jitter      = 0;    /* amount of jitter */
   30 static  int polarity    = 1;    /* polarity */
   31 static  int reliability = 0;    /* reliability emulation */
   32 static  int stability   = 0;    /* stability emulation */
   33 static  int wander      = 0;    /* wander emulation */
   34 
   35 /* create a pulse of possibly poor quality */
   36 static  void    pulse(int port)
   37 {
   38     int         modem_bits  = TIOCM_RTS; /* RTS output */
   39     int     on, off;
   40     struct timespec ns_delay    = {0, 0};
   41     static int  w_phase     = 0;    /* phase of wander */
   42     int     retval;
   43 
   44     if ( reliability > 0 && (random() % reliability) == 0 )
   45         return;
   46     on = polarity ? TIOCMBIC : TIOCMBIS;
   47     off = polarity ? TIOCMBIS : TIOCMBIC;
   48     if ( jitter > 0 )
   49         ns_delay.tv_nsec += random() % (1000 * jitter);
   50     if ( stability > 0 && (random() % (stability + 1)) == 0 )
   51         ns_delay.tv_nsec += random() % (1000 * stability);
   52     if ( wander != 0 )
   53     {
   54         w_phase = (w_phase + 1000 * wander) % 1000000000;
   55         ns_delay.tv_nsec += w_phase;
   56     }
   57     nanosleep(&ns_delay, &ns_delay);
   58     /* create a short pulse */
   59     retval = ioctl(port, on, &modem_bits);
   60     ns_delay.tv_sec = 0, ns_delay.tv_nsec = 500;
   61     /* hopefully 500ns are long enough */
   62     nanosleep(&ns_delay, &ns_delay);
   63     retval |= ioctl(port, off, &modem_bits);
   64     if ( retval == -1 )
   65         perror("ioctl(TIOCMBI[SC])");
   66 }
   67 
   68 /* parse options and generate pulses */
   69 int main(int argc, char *argv[])
   70 {
   71 
   72     int         fd, retval;
   73     struct sched_param  sched;
   74     unsigned long       data;
   75     int         div = 2;
   76     int         out_p;
   77     int         ch;
   78 
   79     while ( (ch = getopt(argc, argv, "j:p:r:s:w:")) != -1 )
   80     {
   81         switch ( ch )
   82         {
   83         case 'j':
   84             jitter = atoi(optarg); break;
   85         case 'p':
   86             polarity = atoi(optarg); break;
   87         case 'r':
   88             reliability = atoi(optarg); break;
   89         case 's':
   90             stability = atoi(optarg); break;
   91         case 'w':
   92             wander = atoi(optarg); break;
   93         case '?':
   94             fprintf (stderr, "Unknown option `-%c'.\n", optopt);
   95             exit(1);
   96         }
   97     }
   98     if ( optind >= argc )
   99     {
  100         fprintf(stderr, "Output port must be specified!\n");
  101         exit(1);
  102     }
  103     if ( (out_p = open(argv[optind], O_RDWR)) < 0 )
  104     {
  105         perror("open()");
  106         fprintf(stderr, "failed to open %s\n", argv[optind]);
  107         exit(1);
  108     }
  109 
  110     fd = open("/dev/rtc", O_RDONLY);
  111     if ( fd == -1 )
  112     {
  113         perror("open(/dev/rtc)");
  114         exit(1);
  115     }
  116 
  117     fprintf(stderr, "RTC PPS generator for Linux 2.0\n");
  118     fprintf(stderr, "jitter = %d\n",  jitter);
  119     fprintf(stderr, "reliability = %d\n",  reliability);
  120     fprintf(stderr, "stability = %d\n",  stability);
  121     fprintf(stderr, "wander = %d\n",  wander);
  122 
  123     /* Turn on periodic interrupts (2 Hz) */
  124     retval = ioctl(fd, RTC_IRQP_SET, 2);
  125     if ( retval == -1 )
  126     {
  127         perror("ioctl(RTC_IRQP_SET)");
  128         exit(1);
  129     }
  130 
  131     retval = ioctl(fd, RTC_PIE_ON, 0);
  132     if ( retval == -1 )
  133     {
  134         perror("ioctl(RTC_PIE_ON)");
  135         exit(1);
  136     }
  137 
  138     read(fd, &data, sizeof(long));  /* wait for RTC interrupt */
  139 
  140     /* become a low priority real-time process */
  141     sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
  142     if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
  143     {
  144         perror("sched_setscheduler()");
  145         exit(1);
  146     }
  147     if ( mlockall(MCL_FUTURE|MCL_CURRENT) == -1 )
  148     {
  149         perror("mlockall()");
  150         exit(1);
  151     }
  152     for ( ;; )
  153     {
  154         if ( read(fd, &data, sizeof(long)) == sizeof(long) )
  155         {
  156             if ( !--div )
  157             {
  158                 pulse(out_p);
  159                 div = 2;
  160             }
  161             if ( (data >> 16) != 0 )
  162                 printf("Missed interrupt (%ld)\n", data >> 16);
  163         }
  164     }
  165 
  166     /* Turn off update interrupts */
  167     retval = ioctl(fd, RTC_PIE_OFF, 0);
  168     if ( retval == -1 )
  169     {
  170         perror("ioctl(RTC_PIE_OFF)");
  171         exit(errno);
  172     }
  173    
  174     close(fd);
  175 } /* end main */