[LinuxPPS] Re: [PATCH 1/1] LinuxPPS: Pulse per Second support for Linux

Rodolfo Giometti giometti at enneenne.com
Wed Mar 14 10:31:46 CET 2007


On Tue, Mar 13, 2007 at 06:48:17PM -0400, Lennart Sorensen wrote:
> 
> I have tried out 3.0.0-rc2 which seems to work pretty well so far (when

Thanks. I just posted to the linux kernel ML the last release
3.0.0. Maybe you can do a "git pull" and try it out. :)

> combined with the patches to the jsm driver I just posted).  It took soe
> work to get ntp's refclock_nmea to work though, since the patch that is
> linked to from the linuxpps page seems out of date.  Here is the patch
> that seems to be working for me, although I am still testing it.  Given
> you know the linuxpps code better perhaps you can see if it looks sane
> to you.
> 
> --- ntpd/refclock_nmea.c.ori	2007-03-13 18:38:01.000000000 -0400
> +++ ntpd/refclock_nmea.c	2007-03-13 18:44:47.000000000 -0400
> @@ -79,6 +79,7 @@
>  #define RANGEGATE	500000	/* range gate (ns) */
>  
>  #define LENNMEA		75	/* min timecode length */
> +#define LENPPS		PPS_MAX_NAME_LEN
>  
>  /*
>   * Tables to compute the ddd of year form icky dd/mm timecode. Viva la
> @@ -99,6 +100,7 @@
>  	pps_params_t pps_params; /* pps parameters */
>  	pps_info_t pps_info;	/* last pps data */
>  	pps_handle_t handle;	/* pps handlebars */
> +	int handle_created;	/* pps handle created flag */
>  #endif /* HAVE_PPSAPI */
>  };
>  
> @@ -147,6 +149,11 @@
>  	register struct nmeaunit *up;
>  	struct refclockproc *pp;
>  	int fd;
> +#ifdef PPS_HAVE_FINDPATH
> +	char id[LENPPS] = "",
> +	     path[LENPPS],
> +	     mylink[LENPPS] = "";    /* just a default device */
> +#endif	/* PPS_HAVE_FINDPATH */
>  	char device[20];
>  
>  	/*
> @@ -201,7 +208,20 @@
>  #else
>              return (0);
>  #endif
> -        }
> +        } else {
> +            struct serial_struct  ss;
> +            if (ioctl(fd, TIOCGSERIAL, &ss) < 0 ||
> +                (
> +		 ss.flags |= ASYNC_HARDPPS_CD,
> +                 ioctl(fd, TIOCSSERIAL, &ss)) < 0) {
> +                 msyslog(LOG_NOTICE, "refclock_nmea: TIOCSSERIAL fd %d, %m", fd);
> +                 msyslog(LOG_NOTICE,
> +                         "refclock_nmea: optional PPS processing not available");
> +            } else {
> +                msyslog(LOG_INFO,
> +                        "refclock_nmea: PPS detection on");
> +            }
> +	}

You should use "setserial" here. Keep in mind that the PPS source
could be _not_ connected with the serial line at all.

>  	/*
>  	 * Allocate and initialize unit structure
> @@ -238,12 +258,26 @@
>  	 * Start the PPSAPI interface if it is there. Default to use
>  	 * the assert edge and do not enable the kernel hardpps.
>  	 */
> +#ifdef PPS_HAVE_FINDPATH
> +	/* Get the PPS source's real name */
> +	//time_pps_readlink(mylink, LENPPS, path, LENPPS);

Remove unneeded code.

> +	time_pps_readlink(device, LENPPS, path, LENPPS);

Test the return value (see the wiki at
http://wiki.enneenne.com/index.php/LinuxPPS_support#How_to_modify_a_refclock_to_work_with_LinuxPPS).

> +	/* Try to find the source */
> +	fd = time_pps_findpath(path, LENPPS, id, LENPPS);
> +	if (fd < 0) {
> +		msyslog(LOG_ERR, "refclock_nmea: cannot find PPS path \"%s\" in the system", path);
> +		return (0);
> +	}
> +	msyslog(LOG_INFO, "refclock_nmea: found PPS source \"%s\" at id #%d on \"%s\"", path, fd, id);
> +#endif	/* PPS_HAVE_FINDPATH */
>  	if (time_pps_create(fd, &up->handle) < 0) {
> -		up->handle = 0;
> +		up->handle_created = 0;
>  		msyslog(LOG_ERR,
>  		    "refclock_nmea: time_pps_create failed: %m");
>  		return (1);
>  	}
> +	up->handle_created = ~0;
>  	return(nmea_ppsapi(peer, 0, 0));
>  #else
>  	return (1);
> @@ -265,8 +299,10 @@
>  	pp = peer->procptr;
>  	up = (struct nmeaunit *)pp->unitptr;
>  #ifdef HAVE_PPSAPI
> -	if (up->handle != 0)
> +	if (up->handle_created) {
>  		time_pps_destroy(up->handle);
> +		up->handle_created = 0;
> +	}
>  #endif /* HAVE_PPSAPI */
>  	io_closeclock(&pp->io);
>  	free(up);
> @@ -374,7 +410,7 @@
>  	/*
>  	 * Convert the timespec nanoseconds field to ntp l_fp units.
>  	 */ 
> -	if (up->handle == 0)
> +	if (!up->handle_created)
>  		return (0);
>  	timeout.tv_sec = 0;
>  	timeout.tv_nsec = 0;

Please, rewiev and test the code and I'll publish it.

Ciao,

Rodolfo

-- 

GNU/Linux Solutions                  e-mail:    giometti at enneenne.com
Linux Device Driver                             giometti at gnudd.com
Embedded Systems                     		giometti at linux.it
UNIX programming                     phone:     +39 349 2432127



More information about the LinuxPPS mailing list