Files
pcas/src/libCom/osi/os/RTEMS/osdTime.cpp
2007-06-19 16:20:36 +00:00

159 lines
3.7 KiB
C++

/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* $Id$
*
* Author: W. Eric Norum
*/
//
/*
* ANSI C
*/
#include <time.h>
#include <limits.h>
/*
* RTEMS
*/
#include <rtems.h>
/*
* EPICS
*/
#define epicsExportSharedSymbols
#include <epicsStdio.h>
#include <epicsThread.h>
#include <cantProceed.h>
#include "iocClock.h"
#include "errlog.h"
extern "C" {
/*
* RTEMS clock rate
*/
rtems_interval rtemsTicksPerSecond;
double rtemsTicksPerSecond_double;
/*
* RTEMS time begins January 1, 1988 (local time).
* EPICS time begins January 1, 1990 (GMT).
*/
#define EPICS_EPOCH_SEC_PAST_RTEMS_EPOCH ((366+365)*86400)
static unsigned long timeoffset;
int epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM )
{
struct tm * pRet = gmtime_r ( pAnsiTime, pTM );
if ( pRet ) {
return epicsTimeOK;
}
else {
return epicsTimeERROR;
}
}
int epicsTime_localtime ( const time_t *clock, struct tm *result )
{
struct tm * pRet = localtime_r ( clock, result );
if ( pRet ) {
return epicsTimeOK;
}
else {
return epicsTimeERROR;
}
}
void
clockInit(void)
{
timeoffset = EPICS_EPOCH_SEC_PAST_RTEMS_EPOCH;
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &rtemsTicksPerSecond);
rtemsTicksPerSecond_double = rtemsTicksPerSecond;
}
static int iocClockGetCurrent(epicsTimeStamp *pDest);
static int iocClockGetEvent(epicsTimeStamp *pDest, int eventNumber);
typedef struct iocClockPvt {
pepicsTimeGetCurrent getCurrent;
pepicsTimeGetEvent getEvent;
}iocClockPvt;
static iocClockPvt *piocClockPvt = 0;
void
iocClockInit(void)
{
if(piocClockPvt) return;
piocClockPvt = (iocClockPvt *)callocMustSucceed(1,sizeof(iocClockPvt),"iocClockInit");
piocClockPvt->getCurrent = iocClockGetCurrent;
piocClockPvt->getEvent = iocClockGetEvent;
}
void
iocClockRegister(pepicsTimeGetCurrent getCurrent, pepicsTimeGetEvent getEvent) {
if(piocClockPvt) {
printf("iocClockRegister: iocClock already initialized\n");
return;
}
piocClockPvt = (iocClockPvt *)callocMustSucceed(1,sizeof(iocClockPvt),"iocClockRegister");
piocClockPvt->getCurrent = getCurrent;
piocClockPvt->getEvent = getEvent;
}
static int
iocClockGetCurrent(epicsTimeStamp *pDest)
{
struct timeval curtime;
rtems_interval t;
rtems_status_code sc;
for (;;) {
sc = rtems_clock_get (RTEMS_CLOCK_GET_TIME_VALUE, &curtime);
if (sc == RTEMS_SUCCESSFUL)
break;
else if (sc != RTEMS_NOT_DEFINED)
return epicsTimeERROR;
sc = rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &t);
if (sc != RTEMS_SUCCESSFUL)
return epicsTimeERROR;
rtems_task_wake_after (t);
}
pDest->nsec = curtime.tv_usec * 1000;
pDest->secPastEpoch = curtime.tv_sec - timeoffset;
return epicsTimeOK;
}
static int
iocClockGetEvent(epicsTimeStamp *pDest, int eventNumber)
{
if (eventNumber==epicsTimeEventCurrentTime)
return iocClockGetCurrent(pDest);
return(epicsTimeERROR);
}
int
epicsTimeGetCurrent (epicsTimeStamp *pDest)
{
if(!piocClockPvt)
iocClockInit();
if(piocClockPvt->getCurrent) return((*piocClockPvt->getCurrent)(pDest));
return(epicsTimeERROR);
}
int
epicsTimeGetEvent (epicsTimeStamp *pDest, int eventNumber)
{
if(!piocClockPvt)
iocClockInit();
if(piocClockPvt->getEvent)
return((*piocClockPvt->getEvent)(pDest,eventNumber));
return(epicsTimeERROR);
}
} /* extern "C" */