This commit adds functionality to increase the sync and pdelay request intervals once gptp synchronization has been achieved. This is useful while running Automotive Profile where the network is usually static.
This is done by setting up a timer when the first sync message is received by the slave. When the timer expires, the slave will send a signaling message which tells the master what interval to switch to. Three new config options have been added to provide this functionality: - sync_interval_update_timer: timeout value (in seconds) for the slave to send out the signaling message. - operLogSyncInterval: slave will ask the master to switch to this interval for sending sync messages when the timer expires. - operLogPdelayReqInterval: the slave will set this interval for pdelay request messages when the timer expires. Signed-off-by: Vedang Patel <vedang.pa...@intel.com> --- config.c | 3 +++ configs/automotive-slave.cfg | 3 +++ configs/default.cfg | 3 +++ fd.h | 3 ++- port.c | 37 +++++++++++++++++++++++++++++++++++++ port_private.h | 4 ++++ ptp4l.8 | 23 +++++++++++++++++++++++ 7 files changed, 75 insertions(+), 1 deletion(-) diff --git a/config.c b/config.c index 6775f66d94c6..9c8f703d4bbd 100644 --- a/config.c +++ b/config.c @@ -264,6 +264,8 @@ struct config_item config_tab[] = { PORT_ITEM_ENU("network_transport", TRANS_UDP_IPV4, nw_trans_enu), GLOB_ITEM_INT("ntpshm_segment", 0, INT_MIN, INT_MAX), GLOB_ITEM_INT("offsetScaledLogVariance", 0xffff, 0, UINT16_MAX), + PORT_ITEM_INT("operLogSyncInterval", 0, INT8_MIN, INT8_MAX), + PORT_ITEM_INT("operLogPdelayReqInterval", 0, INT8_MIN, INT8_MAX), PORT_ITEM_INT("path_trace_enabled", 0, 0, 1), GLOB_ITEM_DBL("pi_integral_const", 0.0, 0.0, DBL_MAX), GLOB_ITEM_DBL("pi_integral_exponent", 0.4, -DBL_MAX, DBL_MAX), @@ -284,6 +286,7 @@ struct config_item config_tab[] = { GLOB_ITEM_DBL("step_threshold", 0.0, 0.0, DBL_MAX), GLOB_ITEM_INT("summary_interval", 0, INT_MIN, INT_MAX), PORT_ITEM_INT("syncReceiptTimeout", 0, 0, UINT8_MAX), + PORT_ITEM_INT("interval_update_timer", 0, 0, INT_MAX), GLOB_ITEM_INT("tc_spanning_tree", 0, 0, 1), GLOB_ITEM_INT("timeSource", INTERNAL_OSCILLATOR, 0x10, 0xfe), GLOB_ITEM_ENU("time_stamping", TS_HARDWARE, timestamping_enu), diff --git a/configs/automotive-slave.cfg b/configs/automotive-slave.cfg index fc8d0c909acd..8ee88708deec 100644 --- a/configs/automotive-slave.cfg +++ b/configs/automotive-slave.cfg @@ -32,3 +32,6 @@ ignore_source_id 1 # Required to quickly correct Time Jumps in master step_threshold 1 ignore_interval_update_req 1 +interval_update_timer 5 +operLogSyncInterval 0 +operLogPdelayReqInterval 2 diff --git a/configs/default.cfg b/configs/default.cfg index 13b30de0c32a..7074c3ba4a3f 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -23,8 +23,10 @@ maxStepsRemoved 255 # logAnnounceInterval 1 logSyncInterval 0 +operLogSyncInterval 0 logMinDelayReqInterval 0 logMinPdelayReqInterval 0 +operLogPdelayReqInterval 0 announceReceiptTimeout 3 syncReceiptTimeout 0 delayAsymmetry 0 @@ -37,6 +39,7 @@ BMCA ptp inhibit_announce 0 ignore_source_id 0 ignore_interval_update_req 0 +interval_update_timer 0 # # Run time options # diff --git a/fd.h b/fd.h index 16420d7e6f86..f733859becfc 100644 --- a/fd.h +++ b/fd.h @@ -20,7 +20,7 @@ #ifndef HAVE_FD_H #define HAVE_FD_H -#define N_TIMER_FDS 8 +#define N_TIMER_FDS 9 /* * The order matters here. The DELAY timer must appear before the @@ -39,6 +39,7 @@ enum { FD_SYNC_TX_TIMER, FD_UNICAST_REQ_TIMER, FD_UNICAST_SRV_TIMER, + FD_INTERVAL_UPDATE_TIMER, FD_RTNL, N_POLLFD, }; diff --git a/port.c b/port.c index 6a2a40993a7c..47bce1642ed9 100644 --- a/port.c +++ b/port.c @@ -1602,11 +1602,16 @@ int port_initialize(struct port *p) p->localPriority = config_get_int(cfg, p->name, "G.8275.portDS.localPriority"); p->logSyncInterval = config_get_int(cfg, p->name, "logSyncInterval"); p->initialLogSyncInterval = p->logSyncInterval; + p->operLogSyncInterval = config_get_int(cfg, p->name, "operLogSyncInterval"); p->logMinPdelayReqInterval = config_get_int(cfg, p->name, "logMinPdelayReqInterval"); p->logPdelayReqInterval = p->logMinPdelayReqInterval; + p->operLogPdelayReqInterval = config_get_int(cfg, p->name, "operLogPdelayReqInterval"); p->neighborPropDelayThresh = config_get_int(cfg, p->name, "neighborPropDelayThresh"); p->min_neighbor_prop_delay = config_get_int(cfg, p->name, "min_neighbor_prop_delay"); p->ignore_interval_update_req = config_get_int(cfg, p->name, "ignore_interval_update_req"); + if (!p->interval_update_timer) { + p->interval_update_timer_set = 1; + } if (config_get_int(cfg, p->name, "asCapable") == AS_CAPABLE_TRUE) { p->asCapable = ALWAYS_CAPABLE; @@ -2241,6 +2246,12 @@ void process_sync(struct port *p, struct ptp_message *m) event = SYNC_MISMATCH; } port_syfufsm(p, event, m); + + if (p->interval_update_timer_set) { + set_tmo_lin(p->fda.fd[FD_INTERVAL_UPDATE_TIMER], + p->interval_update_timer); + p->interval_update_timer_set = 0; + } } /* public methods */ @@ -2383,6 +2394,16 @@ static void port_p2p_transition(struct port *p, enum port_state next) /* fall through */ case PS_SLAVE: port_set_announce_tmo(p); + /* + * Resetting the intervals needed just in case the slave + * restarted and lost time synchronization. + */ + if (p->interval_update_timer) { + p->logPdelayReqInterval = p->logMinPdelayReqInterval; + port_tx_signaling(p, SIGNAL_NO_CHANGE, + SIGNAL_SET_INITIAL, + SIGNAL_NO_CHANGE); + } break; }; } @@ -2511,6 +2532,9 @@ static enum fsm_event bc_event(struct port *p, int fd_index) port_set_announce_tmo(p); } + p->interval_update_timer_set = p->interval_update_timer ? 1 : 0; + p->logSyncInterval = p->initialLogSyncInterval; + delay_req_prune(p); if (clock_slave_only(p->clock) && p->delayMechanism != DM_P2P && port_renew_transport(p)) { @@ -2556,6 +2580,18 @@ static enum fsm_event bc_event(struct port *p, int fd_index) return EV_FAULT_DETECTED; else return EV_NONE; + + case FD_INTERVAL_UPDATE_TIMER: + pr_debug("port %hu: interval update timeout", portnum(p)); + port_clr_tmo(p->fda.fd[FD_INTERVAL_UPDATE_TIMER]); + p->logSyncInterval = p->operLogSyncInterval; + p->logPdelayReqInterval = p->operLogPdelayReqInterval; + if (port_tx_signaling(p, SIGNAL_NO_CHANGE, p->logSyncInterval, + SIGNAL_NO_CHANGE)) { + return EV_FAULT_DETECTED; + } else { + return EV_NONE; + } } msg = msg_allocate(); @@ -2953,6 +2989,7 @@ struct port *port_open(int phc_index, p->link_status = LINK_UP; p->clock = clock; p->trp = transport_create(cfg, transport); + p->interval_update_timer = config_get_int(cfg, p->name, "interval_update_timer"); if (!p->trp) { goto err_port; } diff --git a/port_private.h b/port_private.h index 818989586c35..d55562ff0a66 100644 --- a/port_private.h +++ b/port_private.h @@ -115,9 +115,11 @@ struct port { UInteger8 transportSpecific; UInteger8 localPriority; Integer8 initialLogSyncInterval; + Integer8 operLogSyncInterval; Integer8 logSyncInterval; Enumeration8 delayMechanism; Integer8 logMinPdelayReqInterval; + Integer8 operLogPdelayReqInterval; Integer8 logPdelayReqInterval; UInteger32 neighborPropDelayThresh; int follow_up_info; @@ -147,6 +149,8 @@ struct port { int inhibit_multicast_service; /* interval update timer */ int ignore_interval_update_req; + int interval_update_timer; + int interval_update_timer_set; }; #define portnum(p) (p->portIdentity.portNumber) diff --git a/ptp4l.8 b/ptp4l.8 index c3e26fbbe32f..f6c13123a5ea 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -719,6 +719,29 @@ and the slave does not have any way to know it's identity. The default is 0 .B ignore_interval_update_req Ignore all the incoming signaling requests which request a change in Sync, Announce or Link delay intervals. The default is 0(requests are not ignored). +.TP +.B operLogSyncInterval +The mean time interval between Sync messages. This value is only used by the +slave device when interval_update_timer is enabled. Slave will send this +interval to the master to switch to. This is done via a signaling message after +interval_update_timer expires. It's specified as a power of two in seconds. The +default value is 0 (1 second). +.TP +.B operLogPdelayReqInterval +The mean time interval between Pdelay Request messages. This value is only used +by the slave device when interval_update_timer is enabled. Slave will switch to +the interval specified by this config option after the interval_update_timer +expires. It's specified as a power of two in seconds. The default value is 0 (1 +second). +.TP +.B interval_update_timer +Setup a timer to change Sync and Pdelay Request intevals when it expires. The +timer will be armed when slave receives the first Sync message from the master. +When the timer expires, a signaling message from slave will request the master +to switch to change the Sync interval to the value specified in +operLogSyncInterval. It will also switch Pdelay Request interval to the one +specified in operLogPdelayReqInterval. The timer value is specified in seconds. +The default value is 0 (disabled). .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel