Commit 0141769d authored by Jean-Claude BAU's avatar Jean-Claude BAU Committed by Adam Wujek

Configuration enhancement (follow up)

    - Add new config parameters (l1SyncRxCoherencyIsRequired,...)
    - Add new profile: CUSTOM. It will be mostly used for testing
    - Fix issue on state name: "pre_master" instead of "pre-master"
parent 9b169074
......@@ -61,17 +61,46 @@ struct wrs_shm_head *ppsi_head;
extern struct pp_ext_hooks pp_hooks;
/*
* we need to call calloc, to reset all stuff that used to be static,
* but we'd better have a simple prototype, compatilble with wrs_shm_alloc()
#if CONFIG_EXT_L1SYNC
/**
* Enable the l1sync extension for a given ppsi instance
*/
static void *local_malloc(struct wrs_shm_head *headptr, size_t size)
{
void *retval = malloc(size);
static int enable_l1Sync(struct pp_instance *ppi, Boolean enable) {
if ( enable ) {
ppi->protocol_extension=PPSI_EXT_L1S;
/* Add L1SYNC extension portDS */
if ( !(ppi->portDS->ext_dsport =wrs_shm_alloc(ppsi_head, sizeof(l1e_ext_portDS_t))) ) {
return 0;
}
if (retval)
memset(retval, 0, size);
return retval;
/* Allocate L1SYNC data extension */
if (! (ppi->ext_data = wrs_shm_alloc(ppsi_head,sizeof(struct l1e_data))) ) {
return 0;
}
/* Set L1SYNC state. Must be done here because the init hook is called only in the initializing state. If
* the port is not connected, the initializing is then never called so the L1SYNC state is invalid (0)
*/
L1E_DSPOR_BS(ppi)->L1SyncState=L1SYNC_DISABLED;
L1E_DSPOR_BS(ppi)->L1SyncEnabled=TRUE;
/* Set L1SYNC extension hooks */
ppi->ext_hooks=&l1e_ext_hooks;
}
return 1;
}
#endif
/**
* Enable/disable asymmetry correction
*/
static void enable_asymmetryCorrection(struct pp_instance *ppi, Boolean enable ) {
double delayAsymCoeff;
if ( (ppi->asymmetryCorrectionPortDS.enable=enable)==TRUE ) {
ppi->asymmetryCorrectionPortDS.constantAsymmetry=picos_to_interval(ppi->cfg.constantAsymmetry_ps);
ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient=
(RelativeDifference)(ppi->cfg.delayCoefficient * (double)pow(2.0, REL_DIFF_FRACBITS_AS_FLOAT));
delayAsymCoeff=ppi->cfg.delayCoefficient/(ppi->cfg.delayCoefficient+(double)2.0);
ppi->portDS->delayAsymCoeff=(RelativeDifference)(delayAsymCoeff * (double)pow(2.0, REL_DIFF_FRACBITS_AS_FLOAT));
}
}
int main(int argc, char **argv)
......@@ -83,8 +112,6 @@ int main(int argc, char **argv)
int i, hal_retries;
struct wrs_shm_head *hal_head;
struct hal_shmem_header *h;
void *(*alloc_fn)(struct wrs_shm_head *headptr, size_t size);
alloc_fn = local_malloc;
setbuf(stdout, NULL);
......@@ -165,21 +192,20 @@ int main(int argc, char **argv)
strerror(errno));
exit(1);
}
alloc_fn = wrs_shm_alloc;
ppsi_head->version = WRS_PPSI_SHMEM_VERSION;
ppg = alloc_fn(ppsi_head, sizeof(*ppg));
ppg->defaultDS = alloc_fn(ppsi_head, sizeof(*ppg->defaultDS));
ppg->currentDS = alloc_fn(ppsi_head, sizeof(*ppg->currentDS));
ppg->parentDS = alloc_fn(ppsi_head, sizeof(*ppg->parentDS));
ppg->timePropertiesDS = alloc_fn(ppsi_head,sizeof(*ppg->timePropertiesDS));
ppg = wrs_shm_alloc(ppsi_head, sizeof(*ppg));
ppg->defaultDS = wrs_shm_alloc(ppsi_head, sizeof(*ppg->defaultDS));
ppg->currentDS = wrs_shm_alloc(ppsi_head, sizeof(*ppg->currentDS));
ppg->parentDS = wrs_shm_alloc(ppsi_head, sizeof(*ppg->parentDS));
ppg->timePropertiesDS = wrs_shm_alloc(ppsi_head,sizeof(*ppg->timePropertiesDS));
ppg->rt_opts = &__pp_default_rt_opts;
ppg->max_links = PP_MAX_LINKS;
/* NOTE: arch_data is not in shmem */
ppg->arch_data = malloc( sizeof(struct unix_arch_data));
ppg->pp_instances = alloc_fn(ppsi_head,
ppg->pp_instances = wrs_shm_alloc(ppsi_head,
ppg->max_links * sizeof(*ppi));
if ((!ppg->arch_data) || (!ppg->pp_instances)) {
......@@ -217,14 +243,12 @@ int main(int argc, char **argv)
for (i = 0; i < WRS_NUMBER_PHYSICAL_PORTS; i++) {
Boolean configured=FALSE;
#if CONFIG_PROFILE_HA == 1
sprintf(s, "port %i; iface wri%i; proto raw;"
"profile ha; role auto", i + 1, i + 1);
sprintf(s, "port %i; iface wri%i; proto raw; profile ha", i + 1, i + 1);
configured=TRUE;
#endif
#if CONFIG_PROFILE_WR == 1
if ( ! configured )
sprintf(s, "port %i; iface wri%i; proto raw;"
"profile wr; role auto", i + 1, i + 1);
sprintf(s, "port %i; iface wri%i; proto raw; profile wr", i + 1, i + 1);
#endif
pp_config_string(ppg, s);
}
......@@ -239,57 +263,65 @@ int main(int argc, char **argv)
ppi->iface_name = ppi->cfg.iface_name;
ppi->port_name = ppi->cfg.port_name;
ppi->delayMechanism = ppi->cfg.delayMechanism;
ppi->portDS = alloc_fn(ppsi_head, sizeof(*ppi->portDS));
ppi->servo = alloc_fn(ppsi_head, sizeof(*ppi->servo));
ppi->portDS = wrs_shm_alloc(ppsi_head, sizeof(*ppi->portDS));
ppi->servo = wrs_shm_alloc(ppsi_head, sizeof(*ppi->servo));
ppi->ext_hooks=&pp_hooks; /* Default value. Can be overwritten by an extension */
if (ppi->portDS) {
switch (ppi->cfg.profile) {
#if CONFIG_PROFILE_WR == 1
if ( ppi->cfg.profile==PPSI_PROFILE_WR ) {
case PPSI_PROFILE_WR :
ppi->protocol_extension=PPSI_EXT_WR;
/* Add WR extension portDS */
if ( !(ppi->portDS->ext_dsport =
alloc_fn(ppsi_head, sizeof(struct wr_dsport))) ) {
wrs_shm_alloc(ppsi_head, sizeof(struct wr_dsport))) ) {
goto exit_out_of_memory;
}
/* Allocate WR data extension */
if (! (ppi->ext_data = alloc_fn(ppsi_head,sizeof(struct wr_data))) ) {
if (! (ppi->ext_data = wrs_shm_alloc(ppsi_head,sizeof(struct wr_data))) ) {
goto exit_out_of_memory;
}
/* Set WR extension hooks */
ppi->ext_hooks=&wr_ext_hooks;
}
ppi->cfg.egressLatency_ps=ppi->cfg.ingressLatency_ps=0; /* Forced to 0: Already taken into account in WR calculation */
break;
#endif
#if CONFIG_PROFILE_HA == 1
if ( ppi->cfg.profile==PPSI_PROFILE_HA ) {
ppi->protocol_extension=PPSI_EXT_L1S;
/* Add L1E extension portDS */
if ( !(ppi->portDS->ext_dsport =alloc_fn(ppsi_head, sizeof(l1e_ext_portDS_t))) ) {
goto exit_out_of_memory;
}
/* Allocate WR data extension */
if (! (ppi->ext_data = alloc_fn(ppsi_head,sizeof(struct l1e_data))) ) {
case PPSI_PROFILE_HA :
if ( !enable_l1Sync(ppi,TRUE) )
goto exit_out_of_memory;
/* Force mandatory attributes - Do not take care of the configuration */
L1E_DSPOR_BS(ppi)->rxCoherentIsRequired =
L1E_DSPOR_BS(ppi)->txCoherentIsRequired =
L1E_DSPOR_BS(ppi)->congruentIsRequired=
L1E_DSPOR_BS(ppi)->L1SyncEnabled=TRUE;
L1E_DSPOR_BS(ppi)->optParamsEnabled=FALSE;
enable_asymmetryCorrection(ppi,TRUE);
break;
#endif
case PPSI_PROFILE_PTP :
/* Do not take care of L1SYNC */
enable_asymmetryCorrection(ppi,ppi->cfg.asymmetryCorrectionEnable);
break;
case PPSI_PROFILE_CUSTOM :
#if CONFIG_EXT_L1SYNC
if (ppi->cfg.l1SyncEnabled ) {
if ( !enable_l1Sync(ppi,TRUE) )
goto exit_out_of_memory;
/* Read L1SYNC parameters */
L1E_DSPOR_BS(ppi)->rxCoherentIsRequired =ppi->cfg.l1SyncRxCoherencyIsRequired;
L1E_DSPOR_BS(ppi)->txCoherentIsRequired =ppi->cfg.l1SyncTxCoherencyIsRequired;
L1E_DSPOR_BS(ppi)->congruentIsRequired =ppi->cfg.l1SyncCongruencyIsRequired;
L1E_DSPOR_BS(ppi)->optParamsEnabled=ppi->cfg.l1SyncOptParamsEnabled;
}
/* Set ingress/egress latencies */
ppi->timestampCorrectionPortDS.egressLatency=picos_to_interval(ppi->cfg.egressLatency_ps);
ppi->timestampCorrectionPortDS.ingressLatency=picos_to_interval(ppi->cfg.ingressLatency_ps);
ppi->timestampCorrectionPortDS.messageTimestampPointLatency=0;
ppi->asymmetryCorrectionPortDS.enable=TRUE;
ppi->asymmetryCorrectionPortDS.constantAsymmetry=picos_to_interval(ppi->cfg.constantAsymmetry_ps);
ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient=
(RelativeDifference)(ppi->cfg.delayCoefficient * (double)pow(2.0, REL_DIFF_FRACBITS_AS_FLOAT));
/* Set L1SYNC state. Must be done here because the init hook is called only if the initializing state. It
* the port is not connected, the initializing is then never called so the L1SYNC state is invalid (0)
*/
L1E_DSPOR_BS(ppi)->L1SyncState=L1SYNC_DISABLED;
/* Set L1SYNC extension hooks */
ppi->ext_hooks=&l1e_ext_hooks;
}
#endif
enable_asymmetryCorrection(ppi,ppi->cfg.asymmetryCorrectionEnable);
break;
}
/* Parameters profile independent */
ppi->timestampCorrectionPortDS.egressLatency=picos_to_interval(ppi->cfg.egressLatency_ps);
ppi->timestampCorrectionPortDS.ingressLatency=picos_to_interval(ppi->cfg.ingressLatency_ps);
ppi->timestampCorrectionPortDS.messageTimestampPointLatency=0;
ppi->portDS->masterOnly= ppi->cfg.masterOnly; /* can be overridden in pp_init_globals() */
ppi->portDS->logAnnounceInterval=ppi->cfg.announce_interval;
ppi->portDS->announceReceiptTimeout=ppi->cfg.announce_receipt_timeout;
......@@ -328,5 +360,4 @@ int main(int argc, char **argv)
exit_out_of_memory:;
fprintf(stderr, "ppsi: out of memory\n");
exit(1);
}
......@@ -280,6 +280,7 @@ typedef struct { /* page 72 */
Boolean portEnable; /*draft P1588_v_29: page 124 */
Boolean masterOnly; /*draft P1588_v_29: page 124 */
/** *********************** */
RelativeDifference delayAsymCoeff; /* alpha/(alpha+2). Used to compute delayAsymmetry */
} portDS_t;
/* Time Properties Data Set */
......
......@@ -25,6 +25,7 @@ struct pp_runtime_opts {
int priority2;
int domainNumber;
Boolean externalPortConfigurationEnabled;
Boolean slaveOnly;
void *arch_opts;
};
......@@ -141,14 +142,22 @@ struct pp_instance_cfg {
int sync_interval; /* Sync messages interval */
int min_delay_req_interval; /* delay request messages interval */
int min_pdelay_req_interval;/* pdelay request messages interval */
int l1sync_interval; /* L1SYNC/HA: l1sync messages interval */
int l1sync_receipt_timeout; /* L1SYNC/HA: l1sync messages receipttimeout */
#if CONFIG_EXT_L1SYNC
Boolean l1SyncEnabled; /* L1SYNC: protocol enabled */
Boolean l1SyncRxCoherencyIsRequired; /* L1SYNC: Rx coherency is required */
Boolean l1SyncTxCoherencyIsRequired; /* L1SYNC: Tx coherency is required */
Boolean l1SyncCongruencyIsRequired; /* L1SYNC: Congruency isrRequired */
Boolean l1SyncOptParamsEnabled; /* L1SYNC: Optional parameters enabled */
int l1syncInterval; /* L1SYNC: l1sync messages interval */
int l1syncReceiptTimeout; /* L1SYNC: l1sync messages receipt timeout */
#endif
int64_t egressLatency_ps; /* egressLatency in picos */
int64_t ingressLatency_ps; /* ingressLatency in picos */
int64_t constantAsymmetry_ps; /* constantAsymmetry in picos */
double delayCoefficient; /* fiber delay coefficient as a double */
int desiredState; /* externalPortConfigurationPortDS.desiredState */
Boolean masterOnly; /* masterOnly */
Boolean asymmetryCorrectionEnable; /* asymmetryCorrectionPortDS.enable */
};
/*
......
......@@ -500,10 +500,10 @@ extern int f_simple_int(struct pp_argline *l, int lineno,
#define PPSI_EXT_L1S 2 /* L1SYNC extension */
/* Define the PPSI profiles */
#define PPSI_PROFILE_PTP 0 /* Default PTP profile without extensions */
#define PPSI_PROFILE_WR 1 /* WR profile using WR extension */
#define PPSI_PROFILE_HA 2 /* HA profile using L1S extension, masterOnly and externalPortConfiguration options */
#define PPSI_PROFILE_PTP 0 /* Default PTP profile without extensions */
#define PPSI_PROFILE_WR 1 /* WR profile using WR extension */
#define PPSI_PROFILE_HA 2 /* HA profile using L1S extension, masterOnly and externalPortConfiguration options */
#define PPSI_PROFILE_CUSTOM 3 /* Custom profile. Give free access to all options and attributes */
/* Servo */
extern void pp_servo_init(struct pp_instance *ppi);
......
......@@ -89,14 +89,14 @@ typedef struct { /*draft P1588_v_29: page 100 and 333-335 */
typedef struct { /*draft P1588_v_29: page 101 and 340-341 */
/* configurable members */
Boolean timestampsCorrectedTx;
Boolean timestampsCorrectedTx;
/* dynamic members */
Boolean phaseOffsetTxValid;
Boolean frequencyOffsetTxValid;
struct pp_time phaseOffsetTx;
Timestamp phaseOffsetTxTimesatmp;
struct pp_time frequencyOffsetTx;
Timestamp frequencyOffsetTxTimesatmp;
Boolean phaseOffsetTxValid;
Boolean frequencyOffsetTxValid;
TimeInterval phaseOffsetTx;
Timestamp phaseOffsetTxTimesatmp;
TimeInterval frequencyOffsetTx;
Timestamp frequencyOffsetTxTimesatmp;
} L1SyncOptParamsPortDS_t;
/* Add all extension port DS related structure must be store here */
......
......@@ -78,12 +78,6 @@ static int l1e_init(struct pp_instance *ppi, void *buf, int len)
pp_diag(ppi, ext, 2, "hook: %s -- ext %i\n", __func__,
ppi->protocol_extension);
// init configurable data set members with proper config values
bds->L1SyncEnabled = TRUE;
bds->txCoherentIsRequired = TRUE;
bds->rxCoherentIsRequired = TRUE;
bds->congruentIsRequired = TRUE;
bds->optParamsEnabled = FALSE;
// init dynamic data set members with zeros/defaults
bds->L1SyncLinkAlive = FALSE;
bds->isTxCoherent = FALSE;
......@@ -97,14 +91,14 @@ static int l1e_init(struct pp_instance *ppi, void *buf, int len)
bds->peerIsRxCoherent = FALSE;
bds->peerIsCongruent = FALSE;
/* Init configurable parameters */
bds->logL1SyncInterval=ppi->cfg.l1sync_interval;
bds->L1SyncReceiptTimeout=ppi->cfg.l1sync_receipt_timeout;
bds->logL1SyncInterval=ppi->cfg.l1syncInterval;
bds->L1SyncReceiptTimeout=ppi->cfg.l1syncReceiptTimeout;
/* Init other specific members */
bds->next_state=bds->L1SyncState;
/* Init configuration members of L1SyncOptParamsPortDS */
L1E_DSPOR_OP(ppi)->timestampsCorrectedTx=FALSE;
L1E_DSPOR_OP(ppi)->timestampsCorrectedTx=TRUE;
return 0;
}
......
......@@ -19,6 +19,12 @@
#define MSG_OFFSET_TLV_LENGTH_FIELD (MSG_OFFSET_TLV+2)
#define MSG_OFFSET_TLV_L1SYNC_PEER_CONF (MSG_OFFSET_TLV+4)
#define MSG_OFFSET_TLV_L1SYNC_PEER_ACTIVE (MSG_OFFSET_TLV+5)
#define MSG_OFFSET_TLV_L1SYNC_OPT_CONFIG (MSG_OFFSET_TLV+6)
#define MSG_OFFSET_TLV_L1SYNC_OPT_PHASE_OFFSET_TX (MSG_OFFSET_TLV+7)
#define MSG_OFFSET_TLV_L1SYNC_OPT_PHASE_OFFSET_TX_TIMESTAMP (MSG_OFFSET_TLV+15)
#define MSG_OFFSET_TLV_L1SYNC_OPT_FREQ_OFFSET_TX (MSG_OFFSET_TLV+25)
#define MSG_OFFSET_TLV_L1SYNC_OPT_FREQ_OFFSET_TX_TIMESTAMP (MSG_OFFSET_TLV+33)
#define MSG_OFFSET_TLV_L1SYNC_OPT_RESERVED (MSG_OFFSET_TLV+43)
#define MSG_OFFSET_HEADER_TYPE (MSG_OFFSET_HEADER+0)
......@@ -41,6 +47,8 @@
#define MSG_SET_TLV_L1SYNC_PEER_CONF(buf,val) MSG_GET_8(buf,MSG_OFFSET_TLV_L1SYNC_PEER_CONF)= val
#define MSG_SET_TLV_L1SYNC_PEER_ACTIVE(buf,val) MSG_GET_8(buf,MSG_OFFSET_TLV_L1SYNC_PEER_ACTIVE)=val
#define MSG_SET_TLV_L1SYNC_OPT_CONFIG(buf,val) MSG_GET_8(buf,MSG_OFFSET_TLV_L1SYNC_OPT_CONFIG)=val
#define TLV_TYPE_L1_SYNC 0x8001
#define MSG_L1SYNC_LEN 50
......@@ -51,6 +59,7 @@ int l1e_pack_signal(struct pp_instance *ppi)
PortIdentity targetPortIdentity;
uint8_t local_config, local_active;
L1SyncBasicPortDS_t * bds=L1E_DSPOR_BS(ppi);
UInteger16 msgLen=MSG_L1SYNC_LEN; /* Length of a message with a basic L1SYNC TLV */
memset(&targetPortIdentity,-1,sizeof(targetPortIdentity)); /* cloclk identity and port set all 1's */
/* Generic pack of a signaling message */
......@@ -71,8 +80,19 @@ int l1e_pack_signal(struct pp_instance *ppi)
l1e_print_L1Sync_basic_bitmaps(ppi, local_config,local_active, "Sent");
if ( bds->optParamsEnabled ) {
/* Extended format of L1_SYNC TLV */
L1SyncOptParamsPortDS_t * ods=L1E_DSPOR_OP(ppi);
local_config= (ods->timestampsCorrectedTx? 1 : 0) |
(ods->phaseOffsetTxValid ? 2 : 0 ) |
(ods->frequencyOffsetTxValid ? 4 : 0 );
MSG_SET_TLV_L1SYNC_OPT_CONFIG(buf,local_config);
msgLen+=38;
/* TODO : The extension fields must be filled with L1SyncOptParamsPortDS_t data set */
}
/* header len */
MSG_SET_HEADER_MESSAGE_LENGTH(buf,MSG_L1SYNC_LEN);
MSG_SET_HEADER_MESSAGE_LENGTH(buf,msgLen);
return MSG_L1SYNC_LEN;
}
......
......@@ -39,9 +39,15 @@ struct pp_instance_cfg __pp_default_instance_cfg = {
.min_delay_req_interval=PP_DEFAULT_MIN_DELAY_REQ_INTERVAL,
.min_pdelay_req_interval=PP_DEFAULT_MIN_PDELAY_REQ_INTERVAL,
#if CONFIG_EXT_L1SYNC == 1
.l1sync_interval=L1E_DEFAULT_L1SYNC_INTERVAL,
.l1sync_receipt_timeout=L1E_DEFAULT_L1SYNC_RECEIPT_TIMEOUT,
.l1SyncEnabled=FALSE,
.l1SyncRxCoherencyIsRequired=FALSE,
.l1SyncTxCoherencyIsRequired=FALSE,
.l1SyncCongruencyIsRequired=FALSE,
.l1SyncOptParamsEnabled=FALSE,
.l1syncInterval=L1E_DEFAULT_L1SYNC_INTERVAL,
.l1syncReceiptTimeout=L1E_DEFAULT_L1SYNC_RECEIPT_TIMEOUT,
#endif
.asymmetryCorrectionEnable=FALSE,
.egressLatency_ps=0,
.ingressLatency_ps=0,
.constantAsymmetry_ps=0,
......@@ -78,7 +84,7 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
memcpy(&def->clockQuality, &rt_opts->clock_quality,
sizeof(ClockQuality));
if ( def->slaveOnly ) {
if ( (def->slaveOnly=rt_opts->slaveOnly)==TRUE ) {
if ( def->numberPorts > 1 ) {
/* Check if slaveOnly is allowed
* Only one ppsi instance must exist however n instances on the same physical port
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment