fix PPS with large offsets
This commit is contained in:
parent
e81b53edd2
commit
3f55d2db18
140
gpsd-ppsoffset.patch
Normal file
140
gpsd-ppsoffset.patch
Normal file
@ -0,0 +1,140 @@
|
||||
commit f2357b3fbf3b242f3998d2ce6b5e1ecce1f65125
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Tue May 27 18:08:19 2014 +0200
|
||||
|
||||
Fix PPS with large offsets.
|
||||
|
||||
This was broken by commit 575444. The check if the PPS time isn't
|
||||
referenced with an old message time used PPS offset instead of the
|
||||
difference between local PPS time and local time of the last message.
|
||||
The PPS sample was reported via SHM or chrony socket only if the offset
|
||||
was between -1 and 1000001 seconds.
|
||||
|
||||
Keep the local timestamp of the last fix in struct gps_device_t in
|
||||
addition to the real timestamp and use it to check the PPS delay.
|
||||
Rename the l_offset variable to delay to avoid further confusion.
|
||||
|
||||
diff --git a/gpsd.c b/gpsd.c
|
||||
index 53d68d1..ffaf680 100644
|
||||
--- a/gpsd.c
|
||||
+++ b/gpsd.c
|
||||
@@ -1557,7 +1557,7 @@ static void all_reports(struct gps_device_t *device, gps_mask_t changed)
|
||||
//gpsd_report(context.debug, LOG_PROG, "NTP: No time this packet\n");
|
||||
} else if (isnan(device->newdata.time)) {
|
||||
//gpsd_report(context.debug, LOG_PROG, "NTP: bad new time\n");
|
||||
- } else if (device->newdata.time == device->last_fixtime) {
|
||||
+ } else if (device->newdata.time == device->last_fixtime.real) {
|
||||
//gpsd_report(context.debug, LOG_PROG, "NTP: Not a new time\n");
|
||||
} else if (!device->ship_to_ntpd) {
|
||||
//gpsd_report(context.debug, LOG_PROG, "NTP: No precision time report\n");
|
||||
@@ -1588,7 +1588,8 @@ static void all_reports(struct gps_device_t *device, gps_mask_t changed)
|
||||
/*@-compdef@*/
|
||||
(void)ntpshm_put(device, device->shmIndex, &td);
|
||||
/*@+compdef@*/
|
||||
- device->last_fixtime = device->newdata.time;
|
||||
+ device->last_fixtime.real = device->newdata.time;
|
||||
+ device->last_fixtime.clock = td.clock.tv_sec + td.clock.tv_nsec / 1e9;
|
||||
}
|
||||
#endif /* NTPSHM_ENABLE */
|
||||
|
||||
diff --git a/gpsd.h-tail b/gpsd.h-tail
|
||||
index 8040094..08e0d59 100644
|
||||
--- a/gpsd.h-tail
|
||||
+++ b/gpsd.h-tail
|
||||
@@ -475,7 +475,10 @@ struct gps_device_t {
|
||||
int shmIndexPPS;
|
||||
# endif /* PPS_ENABLE */
|
||||
#endif /* NTPSHM_ENABLE */
|
||||
- volatile timestamp_t last_fixtime; /* so updates happen once */
|
||||
+ volatile struct {
|
||||
+ timestamp_t real;
|
||||
+ timestamp_t clock;
|
||||
+ } last_fixtime; /* so updates happen once */
|
||||
#ifdef PPS_ENABLE
|
||||
#if defined(HAVE_SYS_TIMEPPS_H)
|
||||
pps_handle_t kernelpps_handle;
|
||||
diff --git a/gpsmon.c b/gpsmon.c
|
||||
index b030979..77b6558 100644
|
||||
--- a/gpsmon.c
|
||||
+++ b/gpsmon.c
|
||||
@@ -770,7 +770,7 @@ static void gpsmon_hook(struct gps_device_t *device, gps_mask_t changed UNUSED)
|
||||
report_unlock();
|
||||
|
||||
/* Update the last fix time seen for PPS. FIXME: do this here? */
|
||||
- device->last_fixtime = device->newdata.time;
|
||||
+ device->last_fixtime.real = device->newdata.time;
|
||||
}
|
||||
/*@+observertrans +nullpass +globstate +compdef +uniondef@*/
|
||||
|
||||
diff --git a/ppsthread.c b/ppsthread.c
|
||||
index d9e431e..ed5c7ef 100644
|
||||
--- a/ppsthread.c
|
||||
+++ b/ppsthread.c
|
||||
@@ -238,7 +238,7 @@ static int init_kernel_pps(struct gps_device_t *session)
|
||||
static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
|
||||
{
|
||||
struct gps_device_t *session = (struct gps_device_t *)arg;
|
||||
- double last_fixtime = 0;
|
||||
+ double last_fixtime_real = 0, last_fixtime_clock = 0;
|
||||
#ifndef HAVE_CLOCK_GETTIME
|
||||
struct timeval clock_tv = {0, 0};
|
||||
#endif /* HAVE_CLOCK_GETTIME */
|
||||
@@ -299,7 +299,8 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
|
||||
break;
|
||||
}
|
||||
/* quick, grab a copy of last_fixtime before it changes */
|
||||
- last_fixtime = session->last_fixtime;
|
||||
+ last_fixtime_real = session->last_fixtime.real;
|
||||
+ last_fixtime_clock = session->last_fixtime.clock;
|
||||
|
||||
/*@-noeffect@*/
|
||||
/* get the time after we just woke up */
|
||||
@@ -541,7 +542,7 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
|
||||
log = "Too long for 0.5Hz\n";
|
||||
}
|
||||
#endif /* TIOCMIWAIT */
|
||||
- if ( ok && last_second_used >= last_fixtime ) {
|
||||
+ if ( ok && last_second_used >= last_fixtime_real ) {
|
||||
/* uh, oh, this second already handled */
|
||||
ok = 0;
|
||||
log = "this second already handled\n";
|
||||
@@ -550,7 +551,8 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
|
||||
if (ok) {
|
||||
/* offset is the skew from expected to observed pulse time */
|
||||
double offset;
|
||||
- long l_offset;
|
||||
+ /* delay after last fix */
|
||||
+ double delay;
|
||||
char *log1 = NULL;
|
||||
/* drift.real is the time we think the pulse represents */
|
||||
struct timedrift_t drift;
|
||||
@@ -580,7 +582,7 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
|
||||
*/
|
||||
|
||||
/*@+relaxtypes@*/
|
||||
- drift.real.tv_sec = last_fixtime + 1;
|
||||
+ drift.real.tv_sec = last_fixtime_real + 1;
|
||||
drift.real.tv_nsec = 0; /* need to be fixed for 5Hz */
|
||||
drift.clock = clock_ts;
|
||||
/*@-relaxtypes@*/
|
||||
@@ -589,15 +591,15 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
|
||||
* GPS serial input then use that */
|
||||
offset = (drift.real.tv_sec - drift.clock.tv_sec);
|
||||
offset += ((drift.real.tv_nsec - drift.clock.tv_nsec) / 1e9);
|
||||
- l_offset = (long) offset;
|
||||
- if (0 > l_offset || 1000000 < l_offset) {
|
||||
+ delay = (drift.clock.tv_sec + drift.clock.tv_nsec / 1e9) - last_fixtime_clock;
|
||||
+ if (0.0 > delay || 1.0 < delay) {
|
||||
gpsd_report(session->context->debug, LOG_RAW,
|
||||
- "PPS: no current GPS seconds: %ld\n",
|
||||
- (long)l_offset);
|
||||
+ "PPS: no current GPS seconds: %f\n",
|
||||
+ delay);
|
||||
log1 = "timestamp out of range";
|
||||
} else {
|
||||
/*@-compdef@*/
|
||||
- last_second_used = last_fixtime;
|
||||
+ last_second_used = last_fixtime_real;
|
||||
if (session->thread_report_hook != NULL)
|
||||
log1 = session->thread_report_hook(session, &drift);
|
||||
else
|
@ -15,6 +15,9 @@ Source10: gpsd.service
|
||||
Source11: gpsd.sysconfig
|
||||
Source12: gpsdctl.service
|
||||
|
||||
# Fix PPS with large offsets
|
||||
Patch1: gpsd-ppsoffset.patch
|
||||
|
||||
BuildRequires: dbus-devel dbus-glib-devel ncurses-devel xmlto python-devel
|
||||
BuildRequires: scons desktop-file-utils bluez-libs-devel pps-tools-devel
|
||||
%ifnarch s390 s390x
|
||||
@ -75,6 +78,7 @@ can run on a serial terminal or terminal emulator.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}
|
||||
%patch1 -p1 -b .ppsoffset
|
||||
|
||||
# fix RPATH
|
||||
sed -i 's|sysrpath =.*|sysrpath = ["%{_libdir}"]|' SConstruct
|
||||
|
Loading…
Reference in New Issue
Block a user