From d4b97f497c49b65f6a37bf35c3b513bd4f18e7e6 Mon Sep 17 00:00:00 2001 From: Vincent Cheng Date: Thu, 23 Jan 2020 14:07:22 -0500 Subject: [PATCH] Decouple servo state from automotive profile. The logic for the Automotive Profile added a message interval update mechanism that triggers whenever the servo enters the "stable locked" state. This SERVO_LOCKED_STABLE state is active when the configuration option servo_offset_threshold is non-zero and servo_offset_threshold criteria is satisfied. However, in general, the state of the servo can and should be independent of any profile specific optional behavior. In particular, the "stable locked" state will be used in the future to trigger other kinds useful logic. For example, an upcoming write phase mode feature would like to take advantage of the SERVO_LOCKED_STABLE state to trigger its activation. This patch introduces a proper configuration option to enable transmission of the message interval request that is specific to the Automotive Profile. Signed-off-by: Vincent Cheng Signed-off-by: Richard Cochran --- config.c | 1 + configs/automotive-slave.cfg | 1 + configs/default.cfg | 1 + port.c | 41 +++++++++++++++++----------- port_private.h | 1 + ptp4l.8 | 52 +++++++++++++++++++++--------------- 6 files changed, 60 insertions(+), 37 deletions(-) diff --git a/config.c b/config.c index 53ad788..0cbab4c 100644 --- a/config.c +++ b/config.c @@ -271,6 +271,7 @@ struct config_item config_tab[] = { GLOB_ITEM_STR("manufacturerIdentity", "00:00:00"), GLOB_ITEM_INT("max_frequency", 900000000, 0, INT_MAX), PORT_ITEM_INT("min_neighbor_prop_delay", -20000000, INT_MIN, -1), + PORT_ITEM_INT("msg_interval_request", 0, 0, 1), PORT_ITEM_INT("neighborPropDelayThresh", 20000000, 0, INT_MAX), PORT_ITEM_INT("net_sync_monitor", 0, 0, 1), PORT_ITEM_ENU("network_transport", TRANS_UDP_IPV4, nw_trans_enu), diff --git a/configs/automotive-slave.cfg b/configs/automotive-slave.cfg index 8cc7221..0898660 100644 --- a/configs/automotive-slave.cfg +++ b/configs/automotive-slave.cfg @@ -33,5 +33,6 @@ ignore_source_id 1 step_threshold 1 operLogSyncInterval 0 operLogPdelayReqInterval 2 +msg_interval_request 1 servo_offset_threshold 30 servo_num_offset_values 10 diff --git a/configs/default.cfg b/configs/default.cfg index 119df7b..91f6aaa 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -77,6 +77,7 @@ max_frequency 900000000 clock_servo pi sanity_freq_limit 200000000 ntpshm_segment 0 +msg_interval_request 0 servo_num_offset_values 10 servo_offset_threshold 0 # diff --git a/port.c b/port.c index 6b87bc9..368c3b8 100644 --- a/port.c +++ b/port.c @@ -1131,6 +1131,30 @@ static void port_slave_priority_warning(struct port *p) pr_warning("port %hu: defaultDS.priority1 probably misconfigured", n); } +static void message_interval_request(struct port *p, + enum servo_state last_state, + Integer8 sync_interval) +{ + if (!p->msg_interval_request) + return; + + if (last_state == SERVO_LOCKED) { + p->logPdelayReqInterval = p->operLogPdelayReqInterval; + p->logSyncInterval = p->operLogSyncInterval; + port_tx_interval_request(p, SIGNAL_NO_CHANGE, + p->logSyncInterval, + SIGNAL_NO_CHANGE); + port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0); + } else if (sync_interval != p->operLogSyncInterval) { + /* + * The most likely reason for this to happen is the + * master daemon re-initialized due to some fault. + */ + servo_reset(clock_servo(p->clock)); + port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0); + } +} + static void port_synchronize(struct port *p, tmv_t ingress_ts, struct timestamp origin_ts, @@ -1174,21 +1198,7 @@ static void port_synchronize(struct port *p, port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0); break; case SERVO_LOCKED_STABLE: - if (last_state == SERVO_LOCKED) { - p->logPdelayReqInterval = p->operLogPdelayReqInterval; - p->logSyncInterval = p->operLogSyncInterval; - port_tx_interval_request(p, SIGNAL_NO_CHANGE, - p->logSyncInterval, - SIGNAL_NO_CHANGE); - port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0); - } else if (sync_interval != p->operLogSyncInterval) { - /* - * The most likely reason for this to happen is the - * master daemon re-initialized due to some fault. - */ - servo_reset(clock_servo(p->clock)); - port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0); - } + message_interval_request(p, last_state, sync_interval); break; } } @@ -3029,6 +3039,7 @@ struct port *port_open(const char *phc_device, p->announce_span = transport == TRANS_UDS ? 0 : ANNOUNCE_SPAN; p->follow_up_info = config_get_int(cfg, p->name, "follow_up_info"); p->freq_est_interval = config_get_int(cfg, p->name, "freq_est_interval"); + p->msg_interval_request = config_get_int(cfg, p->name, "msg_interval_request"); p->net_sync_monitor = config_get_int(cfg, p->name, "net_sync_monitor"); p->path_trace_enabled = config_get_int(cfg, p->name, "path_trace_enabled"); p->tc_spanning_tree = config_get_int(cfg, p->name, "tc_spanning_tree"); diff --git a/port_private.h b/port_private.h index bc16d95..82d1801 100644 --- a/port_private.h +++ b/port_private.h @@ -128,6 +128,7 @@ struct port { int hybrid_e2e; int master_only; int match_transport_specific; + int msg_interval_request; int min_neighbor_prop_delay; int net_sync_monitor; int path_trace_enabled; diff --git a/ptp4l.8 b/ptp4l.8 index c4e1464..79bc9d9 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -162,11 +162,12 @@ accuracy of the local clock. It's specified as a power of two in seconds. The default is 0 (1 second). .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). +The Sync message interval to be requested once the clock enters the +SERVO_LOCKED_STABLE state. If the 'msg_interval_request' option is +set, then the local slave port will request the remote master to +switch to the given message rate via a signaling message containing a +Message interval request TLV. This option is specified as a power of +two in seconds, and default value is 0 (1 second). .TP .B logMinDelayReqInterval The minimum permitted mean time interval between Delay_Req messages. A shorter @@ -180,11 +181,11 @@ specified as a power of two in seconds. The default 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). +The Pdelay Request messages interval to be used once the clock enters +the SERVO_LOCKED_STABLE state. If the 'msg_interval_request' option +is set, then the local slave port will adopt this rate when the local +clock enters the "locked stable" state. This option is specified as a +power of two in seconds, and the default value is 0 (1 second). .TP .B inhibit_delay_req Don't send any delay requests. This will need the asCapable config option to be @@ -740,21 +741,28 @@ messages. This is useful when the announce messages are disabled in the master and the slave does not have any way to know it's identity. The default is 0 (disabled). .TP +.B msg_interval_request +This option, when set, will trigger an adjustment to the Sync and peer +delay request message intervals when the clock servo transitions into +the SERVO_LOCKED_STABLE state. The Sync interval will be adjusted via +the signaling mechanism while the pdelay request interval is simply +adjusted locally. The values to use for the new Sync and peer delay +request intervals are specified by the operLogSyncInterval and +operLogPdelayReqInterval options, respectively. +The default value of msg_interval_request is 0 (disabled). +.TP .B servo_num_offset_values -The number of offset values calculated in previously received Sync messages to -consider when adjusting the Sync and Pdelay request intervals. More information -provided in the description of 'offset_threshold'. The default value is 10. +The number of offset values considered in order to transition from the +SERVO_LOCKED to the SERVO_LOCKED_STABLE state. +The transition occurs once the last 'servo_num_offset_values' offsets +are all below the 'servo_offset_threshold' value. +The default value is 10. .TP .B servo_offset_threshold -This value is used by the slave for adjusting the intervals for Sync and Pdelay -request messages. The slave will check the last 'num_offset_values' offsets and -if all those offsets are less than the offset_threshold, it will adjust both -the intervals. The Sync interval is adjusted via the signaling mechanism and -the pdelay request interval is just adjusted locally. The new values to use for -sync message intervals and pdelay request intervals can be indicated by -operLogSyncInterval and operLogPdelayReqInterval respectively. This mechanism -is currently only supported when BMCA == 'noop'. The default -value of offset_threshold is 0 (disabled). +The offset threshold used in order to transition from the SERVO_LOCKED +to the SERVO_LOCKED_STABLE state. The transition occurs once the last +'servo_num_offset_values' offsets are all below the threshold value. +The default value of offset_threshold is 0 (disabled). .SH UNICAST DISCOVERY OPTIONS