From 2fb41d7a36748fe3e3b8c76019f696044ef5e46b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 23 Aug 2019 15:54:32 -0500 Subject: [PATCH] VxWorks: Measure CPU time-base frequency if necessary The BSP routine sysTimeBaseFreq() is optional. If not present or non-functional we measure the frequency of the CPU's time-base counter (against the OS system clock) once at initialization-time. --- .../libcom/src/osi/os/vxWorks/osdMonotonic.c | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/modules/libcom/src/osi/os/vxWorks/osdMonotonic.c b/modules/libcom/src/osi/os/vxWorks/osdMonotonic.c index e0c6b2278..1e6b0a8ad 100644 --- a/modules/libcom/src/osi/os/vxWorks/osdMonotonic.c +++ b/modules/libcom/src/osi/os/vxWorks/osdMonotonic.c @@ -9,10 +9,13 @@ #include #include +#include +#include #define EPICS_EXPOSE_LIBCOM_MONOTONIC_PRIVATE #include "epicsTypes.h" #include "epicsTime.h" +#include "cantProceed.h" #define NS_PER_SEC 1000000000 @@ -23,6 +26,7 @@ union timebase { UINT64 u64; /* epicsMonotonicGet() */ }; +static void measureTickRate(void); #if CPU_FAMILY == PPC #include @@ -46,12 +50,15 @@ void osdMonotonicInit(void) if (sysTimeBaseFreq) { ticksPerSec = sysTimeBaseFreq(); - if (!ticksPerSec) - printf("Warning: Failed to set up monotonic time source.\n"); - /* Warn here only if the BSP routine exists but returned 0 */ + if (ticksPerSec) + return; + + /* This should never happen */ + printf("Warning: sysTimeBaseFreq() present but returned zero.\n"); } - else - ticksPerSec = 0; /* Warn on first use */ + + /* Fall back to measuring */ + measureTickRate(); } @@ -73,8 +80,14 @@ void osdMonotonicInit(void) { ticksPerSec = vxCpuIdGetFreq(); - if (!ticksPerSec) - printf("Warning: Failed to set up monotonic time source.\n"); + if (ticksPerSec) + return; + + /* This should never happen */ + printf("Warning: vxCpuIdGetFreq() returned zero.\n"); + + /* Fall back to measuring */ + measureTickRate(); } @@ -96,13 +109,7 @@ epicsUInt64 epicsMonotonicGet(void) union timebase tbNow; if (!ticksPerSec) { - static int warned = 0; - - if (!warned) { - printf("Warning: Monotonic time source is not available.\n"); - warned = 1; - } - return 0; + cantProceed("Monotonic time source not available.\n"); } TIMEBASEGET(tbNow); @@ -111,3 +118,20 @@ epicsUInt64 epicsMonotonicGet(void) */ return ((long double) tbNow.u64) * NS_PER_SEC / ticksPerSec; } + +static void measureTickRate(void) +{ + union timebase start, end; + int sysTicks = sysClkRateGet(); /* 1 second */ + + printf("osdMonotonicInit: Measuring CPU time-base frequency ..."); + fflush(stdout); + + taskDelay(1); + TIMEBASEGET(start); + taskDelay(sysTicks); + TIMEBASEGET(end); + ticksPerSec = end.u64 - start.u64; + + printf(" %llu ticks/sec.\n", (unsigned long long) ticksPerSec); +}