diff --git a/src/ca/CAref.html b/src/ca/CAref.html index 5145585b6..89d35e14e 100644 --- a/src/ca/CAref.html +++ b/src/ca/CAref.html @@ -6,10 +6,11 @@ EPICS R3.14 Channel Access Reference Manual @@ -411,7 +412,8 @@ other facility is already using the default port numbers. The default Channel Access port numbers have been registered with IANA.

- + + @@ -1330,19 +1332,18 @@ the output.

- + - - - - - - - - - - + diff --git a/src/catools/camonitor.c b/src/catools/camonitor.c index 2be6eb5bd..06ab8a83e 100644 --- a/src/catools/camonitor.c +++ b/src/catools/camonitor.c @@ -45,10 +45,14 @@ void usage (void) " -m : Specify CA event mask to use, with being any combination of\n" " 'v' (value), 'a' (alarm), 'l' (log). Default: va\n" "Timestamps:\n" - " Default: Print absolute timestamps (as reported by CA)\n" - " -r: Relative timestamps (time elapsed since start of program)\n" - " -i: Incremental timestamps (time elapsed since last update)\n" - " -I: Incremental timestamps (time elapsed since last update for this channel)\n" + " Default: Print absolute timestamps (as reported by CA server)\n" + " -t : Specify timestamp source(s) and type, with containing\n" + " 's' = CA server (remote) timestamps\n" + " 'c' = CA client (local) timestamps (shown in '()'s)\n" + " 'n' = No timestamps\n" + " 'r' = relative timestamps (time elapsed since start of program)\n" + " 'i' = incremental timestamps (time elapsed since last update)\n" + " 'I' = incremental timestamps (time elapsed since last update, by channel)\n" "Enum format:\n" " -n: Print DBF_ENUM values as number (default are enum string values)\n" "Arrays: Value format: print number of requested values, then list of values\n" @@ -204,7 +208,7 @@ int main (int argc, char *argv[]) setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ - while ((opt = getopt(argc, argv, ":nhriIm:se:f:g:#:d:0:w:")) != -1) { + while ((opt = getopt(argc, argv, ":nhm:se:f:g:#:d:0:w:t:")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); @@ -212,14 +216,25 @@ int main (int argc, char *argv[]) case 'n': /* Print ENUM as index numbers */ enumAsNr=1; break; - case 'r': /* Select relative timestamps */ - tsType = relative; - break; - case 'i': /* Select incremental timestamps */ - tsType = incremental; - break; - case 'I': /* Select incremental timestamps (by channel) */ - tsType = incrementalByChan; + case 't': /* Select timestamp source(s) and type */ + tsSrcServer = 0; + tsSrcClient = 0; + { + int i = 0; + char c; + while ((c = optarg[i++])) + switch (c) { + case 's': tsSrcServer = 1; break; + case 'c': tsSrcClient = 1; break; + case 'n': break; + case 'r': tsType = relative; break; + case 'i': tsType = incremental; break; + case 'I': tsType = incrementalByChan; break; + default : + fprintf(stderr, "Invalid argument '%c' " + "for option '-t' - ignored.\n", c); + } + } break; case 'w': /* Set CA timeout value */ if(epicsScanDouble(optarg, &caTimeout) != 1) diff --git a/src/catools/tool_lib.c b/src/catools/tool_lib.c index 4bbe08a52..1db0a5503 100644 --- a/src/catools/tool_lib.c +++ b/src/catools/tool_lib.c @@ -28,13 +28,17 @@ #include "tool_lib.h" -/* Time stamps for program start, previous value (used for relative resp. - * incremental times with monitors) */ -static epicsTimeStamp tsStart, tsPrevious; +/* Time stamps for program start, first incoming monitor, + previous value (client and server stamp): + used for relative resp. incremental timestamps with monitors */ +static epicsTimeStamp tsStart, tsFirst, tsPreviousC, tsPreviousS; -static int tsInit = 0; /* Flag: Timestamps init'd */ +static int tsInitS = 0; /* Flag: Server timestamps init'd */ +static int tsInitC = 0; /* Flag: Client timestamps init'd */ -TimeT tsType = absolute; /* Timestamp type flag (-riI options) */ +TimeT tsType = absolute; /* Timestamp type flag (-t option) */ +int tsSrcServer = 1; /* Timestamp source flag (-t option) */ +int tsSrcClient = 0; /* Timestamp source flag (-t option) */ IntFormatT outType = dec; /* For -0.. output format option */ char dblFormatStr[30] = "%g"; /* Format string to print doubles (-efg options) */ @@ -366,80 +370,91 @@ char *dbr2str (const void *value, unsigned type) * **************************************************************************-*/ -#define PRN_TIME_VAL_STS(TYPE,TYPE_ENUM) \ - printAbs = 0; \ - \ - switch (tsType) { \ - case relative: \ - ptsRef = &tsStart; \ - break; \ - case incremental: \ - ptsRef = &tsPrevious; \ - break; \ - case incrementalByChan: \ - ptsRef = &pv->tsPrevious; \ - break; \ - default : \ - printAbs = 1; \ - } \ - \ - if (!printAbs) { \ - if (pv->firstStampPrinted) \ - { \ - printf("%10.4fs ", epicsTimeDiffInSeconds( \ - &(((struct TYPE *)value)->stamp), ptsRef) ); \ - } else { /* First stamp is always absolute */ \ - printAbs = 1; \ - pv->firstStampPrinted = 1; \ - } \ - } \ - \ - if (tsType == incrementalByChan) \ - pv->tsPrevious = ((struct TYPE *)value)->stamp; \ - \ - if (printAbs) { \ - epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, \ - &(((struct TYPE *)value)->stamp)); \ - printf("%s ", timeText); \ - } \ - \ - tsPrevious = ((struct TYPE *)value)->stamp; \ - \ - /* Print count if array */ \ - if ( nElems > 1 ) printf("%lu ", nElems); \ - /* Print Values */ \ - for (i=0; istatus || ((struct TYPE *)value)->severity ) \ - { \ - printf("%s %s\n", \ - stat_to_str(((struct TYPE *)value)->status), \ - sevr_to_str(((struct TYPE *)value)->severity)); \ - } else { \ - printf("\n"); \ +#define PRN_TIME_VAL_STS(TYPE,TYPE_ENUM) \ + printAbs = !pv->firstStampPrinted; \ + \ + ptsNewS = &((struct TYPE *)value)->stamp; \ + ptsNewC = &tsNow; \ + \ + switch (tsType) { \ + case relative: \ + ptsRefC = &tsStart; \ + ptsRefS = &tsFirst; \ + break; \ + case incremental: \ + ptsRefC = &tsPreviousC; \ + ptsRefS = &tsPreviousS; \ + break; \ + case incrementalByChan: \ + ptsRefC = &pv->tsPreviousC; \ + ptsRefS = &pv->tsPreviousS; \ + break; \ + default : \ + printAbs = 1; \ + } \ + \ + if (printAbs) { \ + if (tsSrcServer) { \ + epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewS); \ + printf("%s ", timeText); \ + } \ + if (tsSrcClient) { \ + epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewC); \ + printf("(%s) ", timeText); \ + } \ + pv->firstStampPrinted = 1; \ + } else { \ + if (tsSrcServer) { \ + printf(" %+12.6f ", epicsTimeDiffInSeconds(ptsNewS, ptsRefS) ); \ + } \ + if (tsSrcClient) { \ + printf(" (%+12.6f) ", epicsTimeDiffInSeconds(ptsNewC, ptsRefC) ); \ + } \ + } \ + \ + if (tsType == incrementalByChan) { \ + pv->tsPreviousC = *ptsNewC; \ + pv->tsPreviousS = *ptsNewS; \ + } \ + \ + tsPreviousC = *ptsNewC; \ + tsPreviousS = *ptsNewS; \ + \ + /* Print count if array */ \ + if ( nElems > 1 ) printf("%lu ", nElems); \ + /* Print Values */ \ + for (i=0; istatus || ((struct TYPE *)value)->severity ) \ + { \ + printf("%s %s\n", \ + stat_to_str(((struct TYPE *)value)->status), \ + sevr_to_str(((struct TYPE *)value)->severity)); \ + } else { \ + printf("\n"); \ } void print_time_val_sts (pv* pv, unsigned long nElems) { - char timeText[TIMETEXTLEN]; + char timeText[2*TIMETEXTLEN+2]; int i, printAbs; void* value = pv->value; - epicsTimeStamp *ptsRef = &tsStart; + epicsTimeStamp *ptsRefC, *ptsRefS; /* Reference timestamps (client, server) */ + epicsTimeStamp *ptsNewC, *ptsNewS; /* Update timestamps (client, server) */ epicsTimeStamp tsNow; - if (!tsInit) /* Initialize start timestamp */ - { - epicsTimeGetCurrent(&tsStart); - tsPrevious = tsStart; - tsInit = 1; - } - epicsTimeGetCurrent(&tsNow); epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, &tsNow); + if (!tsInitS) + { + tsFirst = tsNow; + tsInitS = 1; + } + printf("%-30s ", pv->name); if (!pv->onceConnected) printf("*** Not connected (PV not found)\n"); @@ -502,6 +517,12 @@ int create_pvs (pv* pvs, int nPvs, caCh *pCB) int n; int result; int returncode = 0; + + if (!tsInitC) /* Initialize start timestamp */ + { + epicsTimeGetCurrent(&tsStart); + tsInitC = 1; + } /* Issue channel connections */ for (n = 0; n < nPvs; n++) { result = ca_create_channel (pvs[n].name, diff --git a/src/catools/tool_lib.h b/src/catools/tool_lib.h index d0f5d5e79..f811dfb2d 100644 --- a/src/catools/tool_lib.h +++ b/src/catools/tool_lib.h @@ -65,13 +65,16 @@ typedef struct unsigned long reqElems; int status; void* value; - epicsTimeStamp tsPrevious; + epicsTimeStamp tsPreviousC; + epicsTimeStamp tsPreviousS; char firstStampPrinted; char onceConnected; } pv; -extern TimeT tsType; /* Timestamp type flag (-r -i -I options) */ +extern TimeT tsType; /* Timestamp type flag (-t option) */ +extern int tsSrcServer; /* Timestamp source flag (-t option) */ +extern int tsSrcClient; /* Timestamp source flag (-t option) */ extern IntFormatT outType; /* Flag used for -0.. output format option */ extern int enumAsNr; /* Used for -n option (get DBF_ENUM as number) */ extern double caTimeout; /* Wait time default (see -w option) */
Purpose Default
Default:Print absolute timestamps (as reported by CA)Print absolute timestamps (as reported by CA server)
-rRelative timestamps (time elapsed since start of program)
-iIncremental timestamps (time elapsed since last update)
-IIncremental timestamps (time elapsed since last update for this + -t <key>Specify timestamp source(s) and type, with <key> + containing
+ 's' = CA server (remote) timestamps
+ 'c' = CA client (local) timestamps (shown in '()'s)
+ 'n' = no timestamps
+ 'r' = relative timestamps (time elapsed since start of program)
+ 'i' = incremental timestamps (time elapsed since last update)
+ 'I' = incremental timestamps (time elapsed since last update, by channel)