35 #define NSEC_PER_SEC 1000000000 36 #define NTPTimeSyncInterval 60.0 37 #define NTPTimeSyncRetries 4 60 static void NTPTimeSync(
void *
dummy);
65 static const iocshArg *
const ReportArgs[1] = { &ReportArg0 };
66 static const iocshFuncDef ReportFuncDef = {
"NTPTime_Report", 1, ReportArgs};
74 static void ShutdownCallFunc(
const iocshArgBuf *args)
82 static void NTPTime_InitOnce(
void *pprio)
86 NTPTimePvt.synchronize = 1;
87 NTPTimePvt.synchronized = 0;
89 NTPTimePvt.syncsFailed = 0;
100 NTPTimePvt.clockTick = NTPTimePvt.syncTick;
101 NTPTimePvt.clockTime = NTPTimePvt.syncTime;
102 NTPTimePvt.synchronized = 1;
131 NTPTimePvt.synchronize = 0;
138 static void NTPTimeSync(
void *
dummy)
143 NTPTimePvt.synchronize;
157 NTPTimePvt.synchronized) {
158 errlogPrintf(
"NTPTimeSync: NTP requests failing - %s\n",
160 NTPTimePvt.synchronized = 0;
167 errlogPrintf(
"NTPTimeSync: Bad time received from NTP server\n");
168 NTPTimePvt.synchronized = 0;
173 if (ntpDelta <= 0.0 && NTPTimePvt.synchronized) {
174 errlogPrintf(
"NTPTimeSync: NTP time not increasing, delta = %g\n",
176 NTPTimePvt.synchronized = 0;
180 NTPTimePvt.syncsFailed = 0;
181 if (!NTPTimePvt.synchronized) {
188 NTPTimePvt.ticksToSkip = 0;
192 NTPTimePvt.clockTick = tickNow;
193 NTPTimePvt.clockTime = timeNow;
194 NTPTimePvt.synchronized = 1;
197 NTPTimePvt.tickRate = (tickNow - NTPTimePvt.syncTick) / ntpDelta;
198 NTPTimePvt.syncTick = tickNow;
199 NTPTimePvt.syncTime = timeNow;
202 NTPTimePvt.synchronized = 0;
214 if (!NTPTimePvt.synchronized)
220 ticksSince = tickNow - NTPTimePvt.clockTick;
222 if (NTPTimePvt.ticksToSkip <= ticksSince) {
223 if (NTPTimePvt.ticksToSkip) {
224 ticksSince -= NTPTimePvt.ticksToSkip;
225 NTPTimePvt.ticksToSkip = 0;
231 epicsUInt32 secsSince = ticksSince / ticksPerSecond;
233 ticksSince -= secsSince * ticksPerSecond;
234 NTPTimePvt.clockTime.nsec += ticksSince * nsecsPerTick;
239 NTPTimePvt.clockTime.secPastEpoch += secsSince;
240 NTPTimePvt.clockTick = tickNow;
244 *pDest = NTPTimePvt.clockTime;
256 printf(
"NTP driver not initialized\n");
257 }
else if (NTPTimePvt.synchronize) {
258 printf(
"NTP driver %s synchronized with server\n",
259 NTPTimePvt.synchronized ?
"is" :
"is *not*");
260 if (NTPTimePvt.syncsFailed) {
261 printf(
"Last successful sync was %.1f minutes ago\n",
268 "%Y-%m-%d %H:%M:%S.%06f", &NTPTimePvt.syncTime);
269 printf(
"Syncronization interval = %.1f seconds\n",
271 printf(
"Last synchronized at %s\n",
273 printf(
"Current OS tick rate = %u Hz\n",
275 printf(
"Measured tick rate = %.3f Hz\n",
276 NTPTimePvt.tickRate);
280 printf(
"NTP synchronization thread not running.\n");
LIBCOM_API int epicsStdCall epicsTimeFromTimespec(epicsTimeStamp *pDest, const struct timespec *pSrc)
Set epicsTimeStamp from struct timespec
The generalTime framework provides a mechanism for several time providers to be present within the sy...
int generalTimeRegisterCurrentProvider(const char *name, int priority, TIMECURRENTFUN getTime)
void taskwdInsert(epicsThreadId tid, TASKWDFUNC callback, void *usr)
int osdNTPGet(struct timespec *ts)
void epicsStdCall iocshRegister(const iocshFuncDef *piocshFuncDef, iocshCallFunc func)
int NTPTime_Report(int level)
#define epicsTimeOK
Success.
#define S_time_unsynchronized
Provider not synchronized.
LIBCOM_API epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
Wait an the event or until the specified timeout period is over.
void NTPTime_Init(int priority)
LIBCOM_API epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
Create an epicsEvent for use from C code.
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass size)
epicsThreadId epicsStdCall epicsThreadCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
#define NTPTimeSyncInterval
LIBCOM_API size_t epicsStdCall epicsTimeToStrftime(char *pBuff, size_t bufLength, const char *pFormat, const epicsTimeStamp *pTS)
Convert epicsTimeStamp to string. See epicsTime::strftime()
#define EPICS_THREAD_ONCE_INIT
#define epicsEventSignal(ID)
A synonym for epicsEventTrigger().
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
Extended replacement for the Posix exit and atexit routines.
#define POSIX_TIME_AT_EPICS_EPOCH
The EPICS Epoch is 00:00:00 Jan 1, 1990 UTC.
int errlogPrintf(const char *pFormat,...)
APIs for the epicsEvent binary semaphore.
epics::pvData::PVStructurePtr dummy
#define epicsThreadPriorityHigh
void taskwdRemove(epicsThreadId tid)
EPICS time stamp, for use from C code.
#define epicsMutexCreate()
Create an epicsMutex semaphore for use from C code.
Defined by POSIX Real Time.
LIBCOM_API double epicsStdCall epicsTimeDiffInSeconds(const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight)
Time difference between left and right in seconds.
Routines for code that can't continue or return after an error.
#define epicsAtExit(F, A)
Convenience macro to register a function and context value to be run when the process exits...
void NTPTime_Shutdown(void *dummy)
C++ and C descriptions for a thread.
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
#define NTPTimeSyncRetries