The nmea code estimates the device's current time by adding the duration
from the last reading as measured with the local montonic clock.  This
method is fine for a short duration, but the likely frequency offset
between the two clocks limits the long term accuracy.  In addition, if no
recent RMC record is available, probably some kind of error has occurred.
This patch limits the age of the RMC record used for ToD to five seconds.

Signed-off-by: Richard Cochran <richardcoch...@gmail.com>
---
 ts2phc_nmea_master.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/ts2phc_nmea_master.c b/ts2phc_nmea_master.c
index 247d239..b031e65 100644
--- a/ts2phc_nmea_master.c
+++ b/ts2phc_nmea_master.c
@@ -24,6 +24,7 @@
 #include "util.h"
 
 #define BAUD           9600
+#define MAX_RMC_AGE    5000000000ULL
 #define NMEA_TMO       2000 /*milliseconds*/
 
 struct ts2phc_nmea_master {
@@ -186,7 +187,7 @@ static int ts2phc_nmea_master_getppstime(struct 
ts2phc_master *master,
 {
        struct ts2phc_nmea_master *m =
                container_of(master, struct ts2phc_nmea_master, master);
-       tmv_t delay_t1, delay_t2, local_t1, local_t2, rmc;
+       tmv_t delay_t1, delay_t2, duration_since_rmc, local_t1, local_t2, rmc;
        int lstab_error = 0, tai_offset = 0;
        enum lstab_result result;
        struct timespec now;
@@ -214,10 +215,12 @@ static int ts2phc_nmea_master_getppstime(struct 
ts2phc_master *master,
        pr_debug("nmea delay: %" PRId64 " ns",
                 tmv_to_nanoseconds(tmv_sub(delay_t2, delay_t1)));
 
-       //
-       // TODO - check that (local_t2 - local_t1) is smaller than X.
-       //
-       rmc = tmv_add(rmc, tmv_sub(local_t2, local_t1));
+       duration_since_rmc = tmv_sub(local_t2, local_t1);
+       if (tmv_to_nanoseconds(duration_since_rmc) > MAX_RMC_AGE) {
+               pr_err("nmea: rmc time stamp stale");
+               return -1;
+       }
+       rmc = tmv_add(rmc, duration_since_rmc);
        utc_time = tmv_to_nanoseconds(rmc);
        utc_time /= (int64_t) 1000000000;
        *ts = tmv_to_timespec(rmc);
-- 
2.20.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to