/****************************************************************************** * * usrTimeInit - init system time and Real-Time Clock * */ void usrTimeInit(void) { usrTimeSync(); taskSpawn("tTimeSync", 255, 0, 4096, usrTimeAdj, 60, 0,0,0,0,0,0,0,0,0); }
/****************************************************************************** * * usrTimeAdj - routinely adjust system time with the Real-Time Clock * */ STATUS usrTimeAdj( int interval ) { static time_t lastFreq, lastTime, lastPeriod ; FAST time_t freq, t, t1; long dif; struct tm tm ; struct timespec tv ; if( interval == 0) interval = 120 ; freq = sysClkRateGet(); FOREVER { /* sleep until the next iteration */ taskDelay( interval * freq ); taskLock() ; sysRtcGet( &tm ); freq = sysClkRateGet(); t = time (NULL); taskUnlock(); if( t == ERROR ) { char buf[48]; int i=sizeof(buf); asctime_r( &tm, buf, &i ); logMsg("mktime error %s", (int) buf, 0,0,0,0,0); } t1 = mktime( &tm ); dif = t1 - t; /* how many seconds skew */ /* logMsg("t=%d t1=%d dif=%d\n", t, t1, dif, 0,0,0); */ /* if there is a serious difference, do a step adjustment */ if ((abs(dif) > 1) || (freq != lastFreq) ) { if(usrTimeDebug) { char buf[48]; int i=sizeof(buf); asctime_r( &tm, buf, &i ); logMsg("syncing clock %s", (int) buf, 0,0,0,0,0); } usrTimeSync(); /* update statics for next iteration */ lastFreq = freq ; lastPeriod = tv.tv_nsec = 1000000000 / freq ; lastTime = time(NULL) ; } #ifdef __XXX__ else if( dif != 0) { FAST time_t tmp ; /* otherwise, gradually adjust clock to RTC speed */ tv.tv_sec = 0; /* this expression must be carefully ordered, not to * get involved with 64-bit arithmetic which is * incomplete in the current version's library. */ tmp = lastPeriod / ((t - lastTime)*freq); tv.tv_nsec += tmp * dif ; clock_setres( CLOCK_REALTIME, &tv ); if(usrTimeDebug) logMsg("dif %d old period %d ns, new period %d ns, interval %d\n", dif, lastPeriod, tv.tv_nsec, t - lastTime, 0, 0 ); /* update statics for next iteration */ lastFreq = freq ; lastPeriod = tv.tv_nsec ; lastTime = t ; } #endif /*__XXX__*/ } /* FOREVER */ }
/****************************************************************************** * * usrTimeAdj - routinely adjust system time with the Real-Time Clock * */ STATUS usrTimeAdj( int interval ) { static time_t lastFreq, lastTime, lastPeriod ; FAST time_t freq, t, t1; long dif; struct tm tm ; struct timespec tv ; if (interval == 0) interval = 120 ; freq = sysClkRateGet(); FOREVER { /* sleep until the next iteration */ taskDelay( interval * freq ); taskLock() ; sysRtcGet( &tm ); freq = sysClkRateGet(); t = time (NULL); taskUnlock(); if (t == ERROR) { char buf[48]; int i=sizeof(buf); asctime_r( &tm, buf, &i ); logMsg("mktime error %s", (int) buf, 0,0,0,0,0); } t1 = mktime( &tm ); dif = t1 - t; /* how many seconds skew */ /* logMsg("t=%d t1=%d dif=%d\n", t, t1, dif, 0,0,0); */ /* if there is a serious difference, do a step adjustment */ if ((abs(dif) > 1) || (freq != lastFreq)) { if (usrTimeDebug) { char buf[48]; int i=sizeof(buf); asctime_r( &tm, buf, &i ); logMsg("syncing clock %s", (int) buf, 0,0,0,0,0); } usrTimeSync(); /* update statics for next iteration */ lastFreq = freq ; lastPeriod = tv.tv_nsec = 1000000000 / freq ; lastTime = time(NULL) ; } } /* FOREVER */ }