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

From: Lennart Sorensen
Date: Tue Mar 13 2007 - 18:48:35 EST


On Tue, Mar 13, 2007 at 10:38:43PM +0100, Rodolfo Giometti wrote:
> here my new patch for PPS support in Linux.
>
> I tried to follow your suggestions as much possible! Please let me
> know if this new version could be more acceptable.

I have tried out 3.0.0-rc2 which seems to work pretty well so far (when
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");
+ }
+ }

/*
* 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);
+ time_pps_readlink(device, LENPPS, path, LENPPS);
+
+ /* 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;

--
Len Sorensen
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/