Fix the port finite state machine.
The state machine needs to know whether a new master has just been selected in order to choose between the slave and uncalibrated states. Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
c2fad7bd51
commit
222c9bb62b
12
clock.c
12
clock.c
|
@ -230,7 +230,7 @@ struct clock *clock_create(char *phc, struct interface *iface, int count,
|
||||||
c->dds.numberPorts = c->nports = count;
|
c->dds.numberPorts = c->nports = count;
|
||||||
|
|
||||||
for (i = 0; i < c->nports; i++)
|
for (i = 0; i < c->nports; i++)
|
||||||
port_dispatch(c->port[i], EV_INITIALIZE);
|
port_dispatch(c->port[i], EV_INITIALIZE, 0);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ int clock_poll(struct clock *c)
|
||||||
if (EV_STATE_DECISION_EVENT == event)
|
if (EV_STATE_DECISION_EVENT == event)
|
||||||
sde = 1;
|
sde = 1;
|
||||||
else
|
else
|
||||||
port_dispatch(c->port[i], event);
|
port_dispatch(c->port[i], event, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,7 +435,7 @@ struct timePropertiesDS *clock_time_properties(struct clock *c)
|
||||||
static void handle_state_decision_event(struct clock *c)
|
static void handle_state_decision_event(struct clock *c)
|
||||||
{
|
{
|
||||||
struct foreign_clock *best = NULL, *fc;
|
struct foreign_clock *best = NULL, *fc;
|
||||||
int i;
|
int fresh_best = 0, i;
|
||||||
|
|
||||||
for (i = 0; i < c->nports; i++) {
|
for (i = 0; i < c->nports; i++) {
|
||||||
fc = port_compute_best(c->port[i]);
|
fc = port_compute_best(c->port[i]);
|
||||||
|
@ -451,8 +451,10 @@ static void handle_state_decision_event(struct clock *c)
|
||||||
pr_notice("selected best master clock %s",
|
pr_notice("selected best master clock %s",
|
||||||
cid2str(&best->dataset.identity));
|
cid2str(&best->dataset.identity));
|
||||||
|
|
||||||
if (c->best != best)
|
if (c->best != best) {
|
||||||
mave_reset(c->avg_delay);
|
mave_reset(c->avg_delay);
|
||||||
|
fresh_best = 1;
|
||||||
|
}
|
||||||
|
|
||||||
c->best = best;
|
c->best = best;
|
||||||
|
|
||||||
|
@ -482,6 +484,6 @@ static void handle_state_decision_event(struct clock *c)
|
||||||
event = EV_INITIALIZE;
|
event = EV_INITIALIZE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
port_dispatch(c->port[i], event);
|
port_dispatch(c->port[i], event, fresh_best);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
fsm.c
7
fsm.c
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
|
|
||||||
enum port_state ptp_fsm(enum port_state state, enum fsm_event event)
|
enum port_state ptp_fsm(enum port_state state, enum fsm_event event, int mdiff)
|
||||||
{
|
{
|
||||||
enum port_state next = state;
|
enum port_state next = state;
|
||||||
|
|
||||||
|
@ -195,6 +195,7 @@ enum port_state ptp_fsm(enum port_state state, enum fsm_event event)
|
||||||
next = PS_GRAND_MASTER;
|
next = PS_GRAND_MASTER;
|
||||||
break;
|
break;
|
||||||
case EV_RS_SLAVE:
|
case EV_RS_SLAVE:
|
||||||
|
if (mdiff)
|
||||||
next = PS_UNCALIBRATED;
|
next = PS_UNCALIBRATED;
|
||||||
break;
|
break;
|
||||||
case EV_RS_PASSIVE:
|
case EV_RS_PASSIVE:
|
||||||
|
@ -209,7 +210,8 @@ enum port_state ptp_fsm(enum port_state state, enum fsm_event event)
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event)
|
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event,
|
||||||
|
int mdiff)
|
||||||
{
|
{
|
||||||
enum port_state next = state;
|
enum port_state next = state;
|
||||||
|
|
||||||
|
@ -301,6 +303,7 @@ enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event)
|
||||||
next = PS_UNCALIBRATED;
|
next = PS_UNCALIBRATED;
|
||||||
break;
|
break;
|
||||||
case EV_RS_SLAVE:
|
case EV_RS_SLAVE:
|
||||||
|
if (mdiff)
|
||||||
next = PS_UNCALIBRATED;
|
next = PS_UNCALIBRATED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
7
fsm.h
7
fsm.h
|
@ -58,16 +58,19 @@ enum fsm_event {
|
||||||
* Run the state machine for a BC or OC port.
|
* Run the state machine for a BC or OC port.
|
||||||
* @param state The current state of the port.
|
* @param state The current state of the port.
|
||||||
* @param event The event to be processed.
|
* @param event The event to be processed.
|
||||||
|
* @param mdiff Whether a new master has been selected.
|
||||||
* @return The new state for the port.
|
* @return The new state for the port.
|
||||||
*/
|
*/
|
||||||
enum port_state ptp_fsm(enum port_state state, enum fsm_event event);
|
enum port_state ptp_fsm(enum port_state state, enum fsm_event event, int mdiff);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the state machine for a slave only clock.
|
* Run the state machine for a slave only clock.
|
||||||
* @param state The current state of the port.
|
* @param state The current state of the port.
|
||||||
* @param event The event to be processed.
|
* @param event The event to be processed.
|
||||||
|
* @param mdiff Whether a new master has been selected.
|
||||||
* @return The new state for the port.
|
* @return The new state for the port.
|
||||||
*/
|
*/
|
||||||
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event);
|
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event,
|
||||||
|
int mdiff);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
9
port.c
9
port.c
|
@ -311,10 +311,10 @@ static void port_synchronize(struct port *p,
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SERVO_UNLOCKED:
|
case SERVO_UNLOCKED:
|
||||||
case SERVO_JUMP:
|
case SERVO_JUMP:
|
||||||
port_dispatch(p, EV_SYNCHRONIZATION_FAULT);
|
port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
|
||||||
break;
|
break;
|
||||||
case SERVO_LOCKED:
|
case SERVO_LOCKED:
|
||||||
port_dispatch(p, EV_MASTER_CLOCK_SELECTED);
|
port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -794,10 +794,11 @@ struct foreign_clock *port_compute_best(struct port *p)
|
||||||
return p->best;
|
return p->best;
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_dispatch(struct port *p, enum fsm_event event)
|
void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
||||||
{
|
{
|
||||||
enum port_state next = clock_slave_only(p->clock) ?
|
enum port_state next = clock_slave_only(p->clock) ?
|
||||||
ptp_slave_fsm(p->state, event) : ptp_fsm(p->state, event);
|
ptp_slave_fsm(p->state, event, mdiff) :
|
||||||
|
ptp_fsm(p->state, event, mdiff);
|
||||||
|
|
||||||
if (PS_INITIALIZING == next) {
|
if (PS_INITIALIZING == next) {
|
||||||
/*
|
/*
|
||||||
|
|
3
port.h
3
port.h
|
@ -69,8 +69,9 @@ struct foreign_clock *port_compute_best(struct port *port);
|
||||||
*
|
*
|
||||||
* @param port A pointer previously obtained via port_open().
|
* @param port A pointer previously obtained via port_open().
|
||||||
* @param event One of the @a fsm_event codes.
|
* @param event One of the @a fsm_event codes.
|
||||||
|
* @param mdiff Whether a new master has been selected.
|
||||||
*/
|
*/
|
||||||
void port_dispatch(struct port *port, enum fsm_event event);
|
void port_dispatch(struct port *p, enum fsm_event event, int mdiff);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates state machine events based on activity on a port's file
|
* Generates state machine events based on activity on a port's file
|
||||||
|
|
Loading…
Reference in New Issue