[LinuxPPS] LinuxPPS 5.0.0-rc1

Udo van den Heuvel udovdh at xs4all.nl
Fri Aug 10 16:42:03 CEST 2007


Rodolfo Giometti wrote:
>> For a standard GPS unit, with the PPS on the DCD line what am I 
>> supposed to do with this new interface?
>>     (a) open it once, and use it for both GPS and PPS data?
>>     (b) open it twice and use one each for GPS and PPS data?  (as I do currently)
> 
> No, you should do:
> 
>    gps_fd = open("/dev/oncore.serial.0", ...);
> 
>    pps_fd = open("/dev/oncore.pps.0", ...);
> 
>    time_pps_create(pps_fd, &handle);
> 
> and then using gps_fd for standard operations with GPS data, and
> handle for PPS management. Again, the link /dev/oncore.pps.0 points to
> /dev/pps0 or /dev/pps1, etc. (you can use sysfs files to discover
> which is the right source.).
> 
>> I guess I just dont understand your words/example, but it appears to be
>> a significant change from what we have had in the past and have in
>> the previous linuxPPS.
> 
> Yes, you are right! That's why I'm sure we can get _both_ NTP and
> kernel inclusion!
> 
> I'm just updating the wiki for the new 5.x series... please refere to
> it in order to have further info.

I quickly threw together this NMEA patch which should more or less do
what is needed for the latest V5 API.
I don't know if I understood all but at least the code compiles. Don't
know about the workings yet.

Please review and give feedback so we all can learn.

-------------- next part --------------
--- refclock_nmea.c.origineel	2007-08-10 16:16:16.000000000 +0200
+++ refclock_nmea.c	2007-08-10 16:38:01.000000000 +0200
@@ -58,9 +58,10 @@
  * Definitions
  */
 #ifdef SYS_WINNT
-# define DEVICE "COM%d:" 	/* COM 1 - 3 supported */
+# define GPSDEVICE "COM%d:" 	/* COM 1 - 3 supported */
 #else
-# define DEVICE	"/dev/gps%d"	/* name of radio device */
+# define GPSDEVICE	"/dev/nmea.serial.%d"	/* name of radio device */
+# define PPSDEVICE	"/dev/nmea.pps.%d"	/* name of radio device */
 #endif
 #define	SPEED232	B4800	/* uart speed (4800 bps) */
 #define	PRECISION	(-9)	/* precision assumed (about 2 ms) */
@@ -71,6 +72,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
@@ -91,6 +93,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 */
 };
 
@@ -138,16 +141,20 @@
 {
 	register struct nmeaunit *up;
 	struct refclockproc *pp;
-	int fd;
-	char device[20];
+	int gps_fd;
+	int pps_fd;
+	char gpsdevice[20];
+	char ppsdevice[20];
 
 	/*
 	 * Open serial port. Use CLK line discipline, if available.
 	 */
-	(void)sprintf(device, DEVICE, unit);
+	(void)sprintf(gpsdevice, GPSDEVICE, unit);
+	(void)sprintf(ppsdevice, PPSDEVICE, unit);
 
-	fd = refclock_open(device, SPEED232, LDISC_CLK);
-	if (fd <= 0) {
+	gps_fd = refclock_open(gpsdevice, SPEED232, LDISC_CLK);
+	pps_fd = refclock_open(ppsdevice, SPEED232, LDISC_CLK);
+	if (gps_fd <= 0) {
 #ifdef HAVE_READLINK
           /* nmead support added by Jon Miner (cp_n18 at yahoo.com)
            *
@@ -163,11 +170,12 @@
           char *nmea_host;
           int   nmea_port;
           int   len;
+	  int fd;
           struct hostent *he;
           struct protoent *p;
           struct sockaddr_in so_addr;
 
-          if ((len = readlink(device,buffer,sizeof(buffer))) == -1)
+          if ((len = readlink(gpsdevice,buffer,sizeof(buffer))) == -1)
             return(0);
           buffer[len] = 0;
 
@@ -200,7 +208,8 @@
 	 */
 	up = (struct nmeaunit *)emalloc(sizeof(struct nmeaunit));
 	if (up == NULL) {
-		(void) close(fd);
+		(void) close(gps_fd);
+		(void) close(pps_fd);
 		return (0);
 	}
 	memset((char *)up, 0, sizeof(struct nmeaunit));
@@ -208,9 +217,10 @@
 	pp->io.clock_recv = nmea_receive;
 	pp->io.srcclock = (caddr_t)peer;
 	pp->io.datalen = 0;
-	pp->io.fd = fd;
+	pp->io.fd = gps_fd;
 	if (!io_addclock(&pp->io)) {
-		(void) close(fd);
+		(void) close(gps_fd);
+		(void) close(pps_fd);
 		free(up);
 		return (0);
 	}
@@ -230,12 +240,13 @@
 	 * Start the PPSAPI interface if it is there. Default to use
 	 * the assert edge and do not enable the kernel hardpps.
 	 */
-	if (time_pps_create(fd, &up->handle) < 0) {
-		up->handle = 0;
+	if (time_pps_create(pps_fd, &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);
@@ -257,8 +268,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);
@@ -366,7 +379,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;


More information about the LinuxPPS mailing list