Fix error handling: timeout=1500ms, sign of EINTR, cnt==0.
Signed-off-by: Jürgen Appel <[email protected]>
---
ts2phc_pps_sink.c | 66 +++++++++++++++++++++++++++++++++++------------
1 file changed, 49 insertions(+), 17 deletions(-)
diff --git a/ts2phc_pps_sink.c b/ts2phc_pps_sink.c
index d25bc89..1e86849 100644
--- a/ts2phc_pps_sink.c
+++ b/ts2phc_pps_sink.c
@@ -30,8 +30,8 @@ struct ts2phc_pps_sink {
struct ptp_pin_desc pin_desc;
unsigned int polarity;
tmv_t correction;
- uint32_t ignore_lower;
- uint32_t ignore_upper;
+ int pulsewidth;
+ tmv_t last;
struct ts2phc_clock *clock;
};
@@ -175,9 +175,8 @@ static struct ts2phc_pps_sink
*ts2phc_pps_sink_create(struct ts2phc_private *pri
sink->correction = nanoseconds_to_tmv(correction);
pulsewidth = config_get_int(cfg, device, "ts2phc.pulsewidth");
- pulsewidth /= 2;
- sink->ignore_upper = 1000000000 - pulsewidth;
- sink->ignore_lower = pulsewidth;
+ sink->pulsewidth = pulsewidth;
+ sink->last.ns = 0;
sink->clock = ts2phc_clock_add(priv, device);
if (!sink->clock) {
@@ -238,15 +237,40 @@ static void ts2phc_pps_sink_destroy(struct
ts2phc_pps_sink *sink)
static bool ts2phc_pps_sink_ignore(struct ts2phc_private *priv,
struct ts2phc_pps_sink *sink,
+ struct ptp_extts_event event,
struct timespec source_ts)
{
- tmv_t source_tmv = timespec_to_tmv(source_ts);
-
- source_tmv = tmv_sub(source_tmv, priv->perout_phase);
- source_ts = tmv_to_timespec(source_tmv);
-
- return source_ts.tv_nsec > sink->ignore_lower &&
- source_ts.tv_nsec < sink->ignore_upper;
+ tmv_t event_tmv, source_tmv, dt;
+
+ if (sink->pulsewidth == NS_PER_SEC/2) {
+ /*
+ * 1pps has exactly 50% duty cycle: discriminate edges
+ * by CLOCK_REALTIME timestamp, requires CLOCK_REALTIME/
+ * to be approximately correct and stable
+ */
+ source_tmv = timespec_to_tmv(source_ts);
+ source_tmv = tmv_sub(source_tmv, priv->perout_phase);
+ source_ts = tmv_to_timespec(source_tmv);
+
+ return (source_ts.tv_nsec > NS_PER_SEC/4) &&
+ (source_ts.tv_nsec < NS_PER_SEC/4*3);
+ } else {
+ /*
+ * use pulse-width to discriminate rising/falling edges,
+ * does not require CLOCK_REALTIME to run correctly,
+ * tolerates jumps there
+ */
+ event_tmv = pct_to_tmv(event.t);
+ if (sink->last.ns) {
+ dt = tmv_sub(event_tmv, sink->last);
+ sink->last = event_tmv;
+ return ((dt.ns < (NS_PER_SEC / 2)) ^
+ (sink->pulsewidth > (NS_PER_SEC /
2)));
+ } else { /* ignore first event */
+ sink->last = event_tmv;
+ return true;
+ }
+ }
}
static enum extts_result ts2phc_pps_sink_event(struct ts2phc_private *priv,
@@ -277,7 +301,7 @@ static enum extts_result ts2phc_pps_sink_event(struct
ts2phc_private *priv,
}
if (sink->polarity == (PTP_RISING_EDGE | PTP_FALLING_EDGE) &&
- ts2phc_pps_sink_ignore(priv, sink, source_ts)) {
+ ts2phc_pps_sink_ignore(priv, sink, event, source_ts)) {
pr_debug("%s SKIP extts index %u at %lld.%09u src %"
PRIi64 ".%ld",
sink->name, event.index, event.t.sec, event.t.nsec,
@@ -379,17 +403,25 @@ int ts2phc_pps_sink_poll(struct ts2phc_private *priv)
while (!all_sinks_have_events) {
struct ts2phc_pps_sink *sink;
- cnt = poll(polling_array->pfd, priv->n_sinks, 2000);
+ cnt = poll(polling_array->pfd, priv->n_sinks, 1500);
+ /*
+ * timeout =1.5 s ensures that every missing pulse is
+ * detected, even if the PHC is running a little
+ * bit slow, and that a slightly fast PHC causes
+ * no false alarms.
+ */
if (cnt < 0) {
- if (errno == -EINTR) {
+ if (errno == EINTR) {
+ /* signal occurred */
+ pr_err("poll interrupted");
return 0;
} else {
- pr_emerg("poll failed");
+ pr_err("poll failed");
return -1;
} else if (!cnt) {
pr_debug("poll returns zero, no events");
- return 0;
for (i = 0; i < priv->n_sinks; i++) {
--
_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel