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 <vincent.cheng.xh@renesas.com>
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Vincent Cheng 2020-01-23 14:07:22 -05:00 committed by Richard Cochran
parent acd1429645
commit d4b97f497c
6 changed files with 60 additions and 37 deletions

View File

@ -271,6 +271,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_STR("manufacturerIdentity", "00:00:00"), GLOB_ITEM_STR("manufacturerIdentity", "00:00:00"),
GLOB_ITEM_INT("max_frequency", 900000000, 0, INT_MAX), GLOB_ITEM_INT("max_frequency", 900000000, 0, INT_MAX),
PORT_ITEM_INT("min_neighbor_prop_delay", -20000000, INT_MIN, -1), 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("neighborPropDelayThresh", 20000000, 0, INT_MAX),
PORT_ITEM_INT("net_sync_monitor", 0, 0, 1), PORT_ITEM_INT("net_sync_monitor", 0, 0, 1),
PORT_ITEM_ENU("network_transport", TRANS_UDP_IPV4, nw_trans_enu), PORT_ITEM_ENU("network_transport", TRANS_UDP_IPV4, nw_trans_enu),

View File

@ -33,5 +33,6 @@ ignore_source_id 1
step_threshold 1 step_threshold 1
operLogSyncInterval 0 operLogSyncInterval 0
operLogPdelayReqInterval 2 operLogPdelayReqInterval 2
msg_interval_request 1
servo_offset_threshold 30 servo_offset_threshold 30
servo_num_offset_values 10 servo_num_offset_values 10

View File

@ -77,6 +77,7 @@ max_frequency 900000000
clock_servo pi clock_servo pi
sanity_freq_limit 200000000 sanity_freq_limit 200000000
ntpshm_segment 0 ntpshm_segment 0
msg_interval_request 0
servo_num_offset_values 10 servo_num_offset_values 10
servo_offset_threshold 0 servo_offset_threshold 0
# #

41
port.c
View File

@ -1131,6 +1131,30 @@ static void port_slave_priority_warning(struct port *p)
pr_warning("port %hu: defaultDS.priority1 probably misconfigured", n); 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, static void port_synchronize(struct port *p,
tmv_t ingress_ts, tmv_t ingress_ts,
struct timestamp origin_ts, struct timestamp origin_ts,
@ -1174,21 +1198,7 @@ static void port_synchronize(struct port *p,
port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0); port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0);
break; break;
case SERVO_LOCKED_STABLE: case SERVO_LOCKED_STABLE:
if (last_state == SERVO_LOCKED) { message_interval_request(p, last_state, sync_interval);
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);
}
break; break;
} }
} }
@ -3029,6 +3039,7 @@ struct port *port_open(const char *phc_device,
p->announce_span = transport == TRANS_UDS ? 0 : ANNOUNCE_SPAN; p->announce_span = transport == TRANS_UDS ? 0 : ANNOUNCE_SPAN;
p->follow_up_info = config_get_int(cfg, p->name, "follow_up_info"); 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->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->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->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"); p->tc_spanning_tree = config_get_int(cfg, p->name, "tc_spanning_tree");

View File

@ -128,6 +128,7 @@ struct port {
int hybrid_e2e; int hybrid_e2e;
int master_only; int master_only;
int match_transport_specific; int match_transport_specific;
int msg_interval_request;
int min_neighbor_prop_delay; int min_neighbor_prop_delay;
int net_sync_monitor; int net_sync_monitor;
int path_trace_enabled; int path_trace_enabled;

52
ptp4l.8
View File

@ -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). The default is 0 (1 second).
.TP .TP
.B operLogSyncInterval .B operLogSyncInterval
The mean time interval between Sync messages. This value is only used by the The Sync message interval to be requested once the clock enters the
slave device when interval_update_timer is enabled. Slave will send this SERVO_LOCKED_STABLE state. If the 'msg_interval_request' option is
interval to the master to switch to. This is done via a signaling message after set, then the local slave port will request the remote master to
interval_update_timer expires. It's specified as a power of two in seconds. The switch to the given message rate via a signaling message containing a
default value is 0 (1 second). Message interval request TLV. This option is specified as a power of
two in seconds, and default value is 0 (1 second).
.TP .TP
.B logMinDelayReqInterval .B logMinDelayReqInterval
The minimum permitted mean time interval between Delay_Req messages. A shorter 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). The default is 0 (1 second).
.TP .TP
.B operLogPdelayReqInterval .B operLogPdelayReqInterval
The mean time interval between Pdelay Request messages. This value is only used The Pdelay Request messages interval to be used once the clock enters
by the slave device when interval_update_timer is enabled. Slave will switch to the SERVO_LOCKED_STABLE state. If the 'msg_interval_request' option
the interval specified by this config option after the interval_update_timer is set, then the local slave port will adopt this rate when the local
expires. It's specified as a power of two in seconds. The default value is 0 (1 clock enters the "locked stable" state. This option is specified as a
second). power of two in seconds, and the default value is 0 (1 second).
.TP .TP
.B inhibit_delay_req .B inhibit_delay_req
Don't send any delay requests. This will need the asCapable config option to be 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 and the slave does not have any way to know it's identity. The default is 0
(disabled). (disabled).
.TP .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 .B servo_num_offset_values
The number of offset values calculated in previously received Sync messages to The number of offset values considered in order to transition from the
consider when adjusting the Sync and Pdelay request intervals. More information SERVO_LOCKED to the SERVO_LOCKED_STABLE state.
provided in the description of 'offset_threshold'. The default value is 10. 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 .TP
.B servo_offset_threshold .B servo_offset_threshold
This value is used by the slave for adjusting the intervals for Sync and Pdelay The offset threshold used in order to transition from the SERVO_LOCKED
request messages. The slave will check the last 'num_offset_values' offsets and to the SERVO_LOCKED_STABLE state. The transition occurs once the last
if all those offsets are less than the offset_threshold, it will adjust both 'servo_num_offset_values' offsets are all below the threshold value.
the intervals. The Sync interval is adjusted via the signaling mechanism and The default value of offset_threshold is 0 (disabled).
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).
.SH UNICAST DISCOVERY OPTIONS .SH UNICAST DISCOVERY OPTIONS