Skip to content
Snippets Groups Projects
Commit 913a757a authored by Adam Wujek's avatar Adam Wujek
Browse files

proto-standard: store history of grandmasters


Keep information about last 10 grand masters

Signed-off-by: default avatarAdam Wujek <dev_public@wujek.eu>
parent 04a6794d
No related merge requests found
......@@ -576,6 +576,7 @@ int main(int argc, char **argv)
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->gmPrev = wrs_shm_alloc(ppsi_head, sizeof(*ppg->gmPrev));
ppg->rt_opts = &__pp_default_rt_opts;
ppg->max_links = PP_MAX_LINKS;
......
......@@ -321,6 +321,26 @@ struct pp_globals_cfg {
int cur_ppi_n; /* Remember which instance we are configuring */
};
/* Structure to keep historical grandmasters' info */
typedef struct {
ClockIdentity gmId;
PortIdentity parentPortIdentity; /* Peer's port that sent us info about GM */
Enumeration8 gmTimeSource;
UInteger16 gmStepsRemoved;
ClockQuality gmClockQuality;
UInteger8 gmPriority1;
UInteger8 gmPriority2;
unsigned long gmSelectedMs; /* timestamp */
} gmPrevEntry_t;
#define GM_PREV_MAX_ENTRIES 10
typedef struct {
int next_empty; /* Position of the next entry to be used */
int used_entries; /* How many entries are already used */
gmPrevEntry_t entry[GM_PREV_MAX_ENTRIES];
} gmPrev_t;
/*
* Structure for the multi-port ppsi instance.
*/
......@@ -335,6 +355,7 @@ struct pp_globals {
currentDS_t *currentDS; /* page 67 */
parentDS_t *parentDS; /* page 68 */
timePropertiesDS_t *timePropertiesDS; /* page 70 */
gmPrev_t *gmPrev; /* Previous GM entries */
/* Index of the pp_instance receiving the "Ebest" clock */
int ebest_idx;
......
......@@ -124,6 +124,30 @@ void bmc_m3(struct pp_instance *ppi)
pp_gtimeout_disable(GLBS(ppi),PP_TO_GM_BY_BMCA);
}
/* Add information about grandmaster to a list of historical entries */
static void bmc_add_prev_gm_entry(struct pp_instance *ppi)
{
int entry_i;
parentDS_t *parent = DSPAR(ppi);
timePropertiesDS_t *prop = DSPRO(ppi);
struct pp_globals *ppg = GLBS(ppi);
gmPrev_t *gmPrev = ppg->gmPrev;
entry_i = gmPrev->next_empty;
gmPrev->entry[entry_i].parentPortIdentity = parent->parentPortIdentity;
gmPrev->entry[entry_i].gmId = parent->grandmasterIdentity;
gmPrev->entry[entry_i].gmClockQuality = parent->grandmasterClockQuality;
gmPrev->entry[entry_i].gmPriority1 = parent->grandmasterPriority1;
gmPrev->entry[entry_i].gmPriority2 = parent->grandmasterPriority2;
gmPrev->entry[entry_i].gmTimeSource = prop->timeSource;
gmPrev->entry[entry_i].gmStepsRemoved = DSCUR(ppi)->stepsRemoved;
gmPrev->entry[entry_i].gmSelectedMs = TOPS(ppi)->calc_timeout(ppi, 0);
gmPrev->next_empty = (entry_i + 1) % GM_PREV_MAX_ENTRIES;
gmPrev->used_entries = gmPrev->used_entries < GM_PREV_MAX_ENTRIES ? gmPrev->used_entries + 1 : GM_PREV_MAX_ENTRIES;
}
/* ppi->port_idx port is synchronized to Ebest Table 16 (9.3.5) of the spec. */
void bmc_s1(struct pp_instance *ppi,
struct pp_frgn_master *frgn_master)
......@@ -279,6 +303,10 @@ void bmc_s1(struct pp_instance *ppi,
prop->ptpTimescale = ((frgn_master->flagField[1] & FFB_PTP) != 0);
prop->timeSource = frgn_master->timeSource;
/* Store information about the current grandmaster */
if (CONFIG_ARCH_IS_WRS && parent->newGrandmaster)
bmc_add_prev_gm_entry(ppi);
/* Disable timer (if needed) used to go to GM by BMCA */
pp_gtimeout_disable(GLBS(ppi),PP_TO_GM_BY_BMCA);
......
......@@ -82,6 +82,26 @@ struct dump_info dstp_info [] = {
DUMP_FIELD(Enumeration8, timeSource),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT gmPrevEntry_t /* Horrible typedef */
struct dump_info gmPrevEntry_info [] = {
DUMP_FIELD(ClockIdentity, gmId),
DUMP_FIELD(PortIdentity, parentPortIdentity),
DUMP_FIELD(UInteger16, gmStepsRemoved),
DUMP_FIELD(ClockQuality, gmClockQuality),
DUMP_FIELD(UInteger8, gmPriority1),
DUMP_FIELD(UInteger8, gmPriority2),
DUMP_FIELD(Enumeration8, gmTimeSource),
DUMP_FIELD(unsigned_long, gmSelectedMs),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT gmPrev_t /* Horrible typedef */
struct dump_info gmPrev_info [] = {
DUMP_FIELD(int, next_empty),
DUMP_FIELD(int, used_entries),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_servo
struct dump_info servo_state_info [] = {
......@@ -785,6 +805,7 @@ int dump_ppsi_mem(struct wrs_shm_head *head)
currentDS_t *dsc;
parentDS_t *dsp;
timePropertiesDS_t *dstp;
gmPrev_t *gmPrev;
int i;
char prefix[64];
......@@ -811,6 +832,14 @@ int dump_ppsi_mem(struct wrs_shm_head *head)
dstp = wrs_shm_follow(head, ppg->timePropertiesDS);
dump_many_fields(dstp, dstp_info, ARRAY_SIZE(dstp_info),"ppsi.timePropertiesDS");
gmPrev = wrs_shm_follow(head, ppg->gmPrev);
dump_many_fields(gmPrev, gmPrev_info, ARRAY_SIZE(gmPrev_info), "ppsi.gmPrev");
for (i = 0; i < GM_PREV_MAX_ENTRIES /*gmPrev->len*/; i++) {
sprintf(prefix, "ppsi.gmPrev.entry[%d]", i);
dump_many_fields(&gmPrev->entry[i], gmPrevEntry_info, ARRAY_SIZE(gmPrevEntry_info), prefix);
}
#if CONFIG_ARCH_IS_WRS
{
wrs_arch_data_t *arch_data=wrs_shm_follow(head, WRS_ARCH_G(ppg));
......
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