RTI Connext Micro  Version 2.4.1.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
OSAPI Time

Data Structures

struct  OSAPI_NtpTime
 NtpTime API. More...

Macros

#define OSAPI_NTP_TIME_SEC_MAX   ((RTI_INT32)0x7fffffff)
#define OSAPI_NTP_TIME_FRAC_MAX   ((RTI_UINT32)0xffffffff)
#define OSAPI_NtpTime_zero(time)
 Set struct OSAPI_NtpTime time to zero.
#define OSAPI_NtpTime_set_max(time)
 Set struct OSAPI_NtpTime time to maximum value.
#define OSAPI_NtpTime_from_millisec(time, s, msec)
 Macro to convert from seconds and milliseconds to struct OSAPI_NtpTime format.
#define OSAPI_NtpTime_to_millisec(s, msec, time)
 Macro to convert from struct OSAPI_NtpTime to seconds and milliseconds.
#define OSAPI_NtpTime_from_microsec(time, s, usec)
 Macro to convert from seconds and microseconds to struct OSAPI_NtpTime format.
#define OSAPI_NtpTime_to_microsec(s, usec, time)
 Macro to convert from struct OSAPI_NtpTime to seconds and microseconds.
#define OSAPI_NtpTime_from_nanosec(time, s, nsec)
 Macro to convert from seconds and nanoseconds to struct OSAPI_NtpTime format.
#define OSAPI_NtpTime_to_nanosec(s, nsec, time)
 Macro to convert from struct OSAPI_NtpTime to seconds and nanoseconds.
#define OSAPI_NTP_TIME_PRECISION_BITS_DEFAULT   7
 Precision used in bit manipulation for struct OSAPI_NtpTime fraction conversions.
#define OSAPI_NtpTime_from_fraction(time, numerator, denominator_per_sec)
 Macro to convert numerator/denom_per_sec into NTP time.
#define OSAPI_NtpTime_to_fraction(numerator, denominator_per_sec, time)
 Transforms from struct OSAPI_NtpTime to any integral fraction of a second without using floating point operations.
#define OSAPI_NtpTime_compare(time1, time2)
 Compare two OSAPI_NtpTimes.
#define OSAPI_NtpTime_is_infinite(time)
#define OSAPI_NtpTime_add(answer, t1, t2)
 answer = t1 + t2.
#define OSAPI_NtpTime_subtract(answer, t1, t2)
 answer = t1 - t2.
#define OSAPI_NtpTime_left_shift(answer, time, shift)
 answer = time << shift.
#define OSAPI_NtpTime_right_shift(answer, time, shift)
 answer = time >> shift.
#define OSAPI_NtpTime_increment(answer, time)
 answer += time.
#define OSAPI_NtpTime_decrement(answer, time)
 Decrement one struct OSAPI_NtpTime value by another struct OSAPI_NtpTime value.
#define OSAPI_NtpTime_increment_infinitesimally(time)   ((++((time)->frac)) == 0) ? ++(time)->sec : 0
 time = time + 1 fraction (~200 picoseconds).
#define OSAPI_NtpTime_is_zero(time)
#define OSAPI_NTP_TIME_ZERO   {0,0}
 Zero time.
#define OSAPI_NTP_TIME_MAX   {OSAPI_NTP_TIME_SEC_MAX,OSAPI_NTP_TIME_FRAC_MAX}
#define OSAPI_NTP_TIME_NSEC_PER_SEC   (1000000000)
#define OSAPI_NTP_TIME_USEC_PER_SEC   (1000000)
#define OSAPI_NTP_TIME_MSEC_PER_SEC   (1000)
#define OSAPI_NTP_TIME_NSEC_PER_USEC   (1000)
#define OSAPI_NTP_TIME_USEC_PER_MSEC   (1000)
#define OSAPI_NTP_TIME_SEC_PER_SEC   (1)
#define OSAPI_NTP_TIME_NSEC_PER_MSEC   (1000000)

Typedefs

typedef struct OSAPI_NtpTime OSAPI_NtpTime
 NtpTime API.

Detailed Description


Macro Definition Documentation

#define OSAPI_NTP_TIME_SEC_MAX   ((RTI_INT32)0x7fffffff)

The maximum number of seconds that can be represented using NTP time.

#define OSAPI_NTP_TIME_FRAC_MAX   ((RTI_UINT32)0xffffffff)

The largest possible value of the fraction field in NTP time.

#define OSAPI_NtpTime_zero (   time)
Value:
{ \
(time)->sec = 0; \
(time)->frac = 0; \
}

Set struct OSAPI_NtpTime time to zero.

Parameters:
time(struct OSAPI_NtpTime*) Pointer to struct OSAPI_NtpTime struct that needs to be set to zero.
#define OSAPI_NtpTime_set_max (   time)
Value:
{ \
(time)->sec = OSAPI_NTP_TIME_SEC_MAX; \
(time)->frac = OSAPI_NTP_TIME_FRAC_MAX; \
}

Set struct OSAPI_NtpTime time to maximum value.

Parameters:
time(struct OSAPI_NtpTime*) Pointer to struct OSAPI_NtpTime struct that needs to be set to its maximum possible value.

The maximum possible value equals:

(time).sec = OSAPI_NTP_TIME_SEC_MAX (time).frac = OSAPI_NTP_TIME_FRAC_MAX

#define OSAPI_NtpTime_from_millisec (   time,
  s,
  msec 
)
Value:
{ \
register RTI_UINT32 ms = msec; \
(time)->sec = s; \
(time)->frac = (ms<<22) + ((ms*393)<<8); \
}

Macro to convert from seconds and milliseconds to struct OSAPI_NtpTime format.

Parameters:
time(struct OSAPI_NtpTime) contains the answer.
s(integer) Seconds to convert.
msec(millisecond) Fraction portion (less than 1000).
    struct OSAPI_NtpTime time;
    long sec, msec;
    sec = 10;
    msec = 577;

    OSAPI_NtpTime_packFromMillisec(time, sec, msec);

After the above call is made, the variable time will contain the equivalent timestamp in struct OSAPI_NtpTime representation.

This macro assumes that msec<1000. It is the caller's responsibility to ensure this. This is done for performance reasons (the extra check slows the execution by a factor of 5). If msec may be greater than 1000, you can invoke the macro as follows:

    OSAPI_NtpTime_packFromMillisec(time, sec + msec/1000, msec%1000);

This macro only evaluates its arguments once, so it is safe to invoke it with an argument that has side effects; that is, if you write:

    RTI_UINT32 count = 10;
    OSAPI_NtpTime_packFromMillisec(time, sec, count++)

After the macro count is guaranteed to be 11.

The accuracy of this conversion over the whole range of millisecond values is 0.013 milliseconds.

This is a fairly efficient macro. On a 400MHz Pentium-II Linux box the execution time is about 0.06 usec.

     2^22*time.frac = ms + ms/2^6 + ms/2^7 + ms/2^11 + ms/2^14 + 1.3e-5
                    = ms + ms*393/2^14;
          time.frac = (ms<<22) + (ms<<16) + (ms<<15) + (ms<<11) + (ms<<8)
                    = (ms<<22) + ((ms*393)<<8)
See also:
struct OSAPI_NtpTime OSAPI_NtpTime_unpackToMillisec
#define OSAPI_NtpTime_to_millisec (   s,
  msec,
  time 
)
Value:
{ \
*(s) = (time)->sec; \
*(msec) = ((time)->frac - ((time)->frac>>6) - ((time)->frac>>7) + (1<<21))>>22; \
if( ((*(msec))>=1000)&&((*(s))!=0x7FFFFFFF) ) { (*(msec)) -= 1000; (*(s))++; } \
}

Macro to convert from struct OSAPI_NtpTime to seconds and milliseconds.

Parameters:
s(integer) Holds the seconds answer.
msec(integer) Holds the millisecond answer.
time(struct OSAPI_NtpTime) The time to convert to seconds and milliseconds.

This macro does not check for overflow, so for a near-infinite time value, the conversion result may end up being negative. It is the responsibility of the user to avoid passing these large time values.

Use as indicated by the following code:

}
    struct OSAPI_NtpTime time;
    long sec, msec;

    time.sec  = 10;
    time.frac = 577;

    OSAPI_NtpTime_unpackToMillisec(sec, msec, time);

After the above call is made, the variables "sec" and "msec" will contain the equivalent timestamp.

The accuracy of this conversion over the whole range of struct OSAPI_NtpTime values is 0.5 milliseconds, except for ntp values above {0x7fffffff, 0x7fffffff}, accuracy is up to nearly 1 millisecond.

This is a fairly efficient macro. On a 400MHz Pentium-II Linux box the execution time is about 0.08 usec.

     ms/2^22 = frac*1000/1024 = frac*(1 - 24/1024) = frac*(1 - 3/2^7) =
               frac*(1 - 1/2^6 - 1/2^7)
See also:
struct OSAPI_NtpTime OSAPI_NtpTime_packFromMillisec
#define OSAPI_NtpTime_from_microsec (   time,
  s,
  usec 
)
Value:
{ \
register RTI_UINT32 us = usec; \
(time)->sec = s; \
(time)->frac = (us<<12)+ ((us*99)<<1)+ ((us*15 + ((us*61)>>7))>>4); \
}

Macro to convert from seconds and microseconds to struct OSAPI_NtpTime format.

Parameters:
time(struct OSAPI_NtpTime) to contain the answer.
s(integer) seconds of the time to covert.
usec(integer) microseconds fraction to convert from.

This macro does not check for overflow, so for a near-infinite time value, the conversion result may end up being negative. It is the caller's responsibility to avoid passing these large time values.

Use as indicated by the following code:

    struct OSAPI_NtpTime ntp;
    long sec, usec;
    sec  = 10;
    usec = 577;

    OSAPI_NtpTime_packFromMicrosec(ntp, sec, usec);

After the above call is made, the variable ntp will contain the equivalent time stamp in struct OSAPI_NtpTime representation.

This macro assumes that msec<1000000. It is the caller's responsibility to ensure this. This is done for performance reasons, the extra check slows the execution a factor of 5! If msec may be greater than 1000000, you can invoke the macro as follows:

    OSAPI_NtpTime_packFromMicrosec(ntp, sec + usec/1000000, usec%1000000);

This macro only evaluates its arguments once, so it is safe to invoke it with an argument that has side effects; that is, if you write:

    RTI_UINT32 count = 10;
    OSAPI_NtpTime_packFromMicrosec(ntp, sec, count++)

After the macro, count is guaranteed to be 11.

The accuracy of this conversion over the whole range of microsecond values is 0.0028 microseconds.

This is a fairly efficient macro. On a 400MHz Pentium-II Linux box the execution time is about 0.08 usec.

    2^12 * ntp.frac = us + us/2^5  + us/2^6  + us/2^10 + us/2^11
                         + us/2^13 + us/2^14 + us/2^15 + us/2^16
                         + us/2^18 + us/2^19 + us/2^20 + us/2^21
                         + us/2^23 + 3e-9
                    = us + us*99/2^11 + us*15/2^16 + us*61/2^23
           ntp.frac = (us<<12) + (us<<7) + (us<<6) + (us<<2) + (us<<1)
                               + (us>>1) + (us>>2) + (us>>3) + (us>>4)
                               + (us>>6) + (us>>7) + (us>>8) + (us>>9) + (us>>11)
                    = (us<<12) + ((us*99)<<1)+ ((us*15)>>4)+ ((us*61)>>11)
#define OSAPI_NtpTime_to_microsec (   s,
  usec,
  time 
)
Value:
{ \
register RTI_UINT32 rtiNtpTemp = (time)->frac; \
*(s) = (time)->sec; \
*(usec) = ((time)->frac - (rtiNtpTemp>>5)-(rtiNtpTemp>>7)-(rtiNtpTemp>>8)- \
(rtiNtpTemp>>9)-(rtiNtpTemp>>10) - (rtiNtpTemp>>12) - \
(rtiNtpTemp>>13)-(rtiNtpTemp>>14) + (1<<11)) >> 12; \
if( ((*(usec)) >= 1000000) && ((*(s))!=0x7FFFFFFF) ) { \
(*(usec)) -= 1000000; \
(*(s))++; \
} \
}

Macro to convert from struct OSAPI_NtpTime to seconds and microseconds.

Parameters:
s(integer) Holds the second portion.
usec(integer) holds the microsecond fraction.
time(struct OSAPI_NtpTime) to be converted.

This macro does not check for overflow, so for a near-infinite time value, the conversion result may end up being negative. It is the caller's responsibility to avoid passing these large time values.

Use as indicated by the following code:

    struct OSAPI_NtpTime ntp;
    long sec, usec;

    ntp.sec  = 10;
    ntp.frac = 577;

    OSAPI_NtpTime_unpackToMicrosec(sec, usec, ntp);

After the above call is made, the variables "sec" and "usec" will contain the equivalent timestamp.

The accuracy of this conversion over the whole range of struct OSAPI_NtpTime values is 0.5 microseconds, except for ntp value above {0x7fffffff, 0x7fffffff}, accuracy is up to nearly 1 millisecond.

This is a fairly efficient macro. On a 400MHz Pentium-II Linux box the execution time is about 0.12 usec.

     us = frac*1000000/2^20 = frac*( 1 - 48576/2^20 )
        = frac*(1 - 47/2^10 - 7/2^14)
        = frac - ((47*frac)>>10) - ((7*frac)>>14)
        = frac - (frac>>5)-(frac>>7)-(frac>>8)-(frac>>9)-(frac>>10)
             - (frac>>12)-(frac>>13)-(frac>>14)
#define OSAPI_NtpTime_from_nanosec (   time,
  s,
  nsec 
)
Value:
{ \
register RTI_UINT32 ns = nsec; \
(time)->sec = s; \
(time)->frac = (ns<<2) + ((ns + (ns>>3) + (ns>>5) + (ns>>6) + \
(ns>>7) + (ns>>13) + (ns>>15) + (ns>>16) + (ns>>17) + \
(ns>>18) + (ns>>19) + (ns>>21) + (ns>>27) + (ns>>30))>>2); \
}

Macro to convert from seconds and nanoseconds to struct OSAPI_NtpTime format.

Parameters:
time(struct OSAPI_NtpTime) Holds the answer.
s(integer) Seconds to convert from.
nsec(integer) Nanosecond fraction to convert from.

Use as indicated by the following code:

    struct OSAPI_NtpTime time;
    long sec, nsec;
    sec = 10;
    nsec = 577;

    OSAPI_NtpTime_packFromNanosec(time, sec, msec);

After the above call is made, the variable time will contain the equivalent timestamp in struct OSAPI_NtpTime representation.

This macro assumes that nsec<1000000000. It is the caller's responsibility to ensure this. This is done for performance reasons (the extra check slows the execution a factor of 5). If msec may be greater than 1000000, you can invoke the macro as follows:

}
    OSAPI_NtpTime_packFromNanosec(time, sec + nsec/1000000000, nsec%1000000000);

This macro only evaluates its arguments once, so it is safe to invoke it with an argument that has side effects; that is, if you write:

    RTI_UINT32 count = 10;
    OSAPI_NtpTime_packFromNanosec(time, sec, count++)

After the macro, count is guaranteed to be 11.

The accuracy of this conversion over the whole range of nanosecond values is 0.5 nanoseconds, except for ntp value above {0x7fffffff, 0x7fffffff}, accuracy is up to nearly 1 millisecond.

This is a fairly efficient macro. On a 400MHz Pentium-II Linux box the execution time is about 0.10 usec.

     2^32/10^9 ns = 4*ns + ns/2^2  + ns/2^5  + ns/2^7 + ns/2^8  + ns/2^9   +
                           ns/2^15 + ns/2^17 + ns/2^18 + ns/2^19 + ns/2^20 +
                           ns/2^21 + ns/2^23 + ns/2^29 + ns/2^32

     2^32/10^9 ns = 4*ns + (ns     + ns/2^3  + ns/2^5 + ns/2^6  + ns/2^7   +
                           ns/2^13 + ns/2^15 + ns/2^16 + ns/2^17 + ns/2^18 +
                           ns/2^19 + ns/2^21 + ns/2^27 + ns/2^30)*(1/2^2)
#define OSAPI_NtpTime_to_nanosec (   s,
  nsec,
  time 
)
Value:
{ \
register RTI_UINT32 rtiNtpTemp = (time)->frac>>1; \
register RTI_UINT32 rtiNtpDelta; \
*(s) = (time)->sec; \
rtiNtpDelta = (rtiNtpTemp) + (rtiNtpTemp>>4) + (rtiNtpTemp>>5) + \
(rtiNtpTemp>>8) + (rtiNtpTemp>>10) + (rtiNtpTemp>>13) + \
(rtiNtpTemp>>14)+ (rtiNtpTemp>>16) + (rtiNtpTemp>>17); \
*(nsec) = ((time)->frac - ((rtiNtpDelta+4)>>3) + 1) >> 2; \
if( ((*(nsec))>=1000000000) && ((*(s))!=0x7FFFFFFF) ) { \
(*(nsec)) -= 1000000000; \
(*(s))++; \
} \
}

Macro to convert from struct OSAPI_NtpTime to seconds and nanoseconds.

Parameters:
s(integer) Second of the time to covert.
nsec(integer) Nanosecond fraction to convert.
time(struct OSAPI_NtpTime) to convert from.

Use as indicated by the following code:

    struct OSAPI_NtpTime time;
    long sec, nsec;
    time.sec  = 10;
    time.frac = 577;

    OSAPI_NtpTime_unpackToNanosec(sec, nsec, time);

After the above call is made, the variables "sec" and "nsec" will contain the equivalent timestamp.

The accuracy of this conversion over the whole range of struct OSAPI_NtpTime values is 0.5 nsec.

This is a fairly efficient macro. On a 400MHz Pentium-II Linux box the execution time is about 0.09 usec.

Given that 294967296 = 0x1194d800 and:

      4*ns = frac*4000000000/2^32 = frac*(1 - 294967296/2^32)
           = frac*(1 - 1/2^4 - 1/2^8 - 9/2^12 - 4/2^16 - 13/2^20 - 8/2^24)
           = frac*(1 - 1>>4 - 1>>8 - 1>>9 - 1>>12 - 1>>14 - 1>>17 - 1>>18 -
               1>>20 - 1>>21)
#define OSAPI_NTP_TIME_PRECISION_BITS_DEFAULT   7

Precision used in bit manipulation for struct OSAPI_NtpTime fraction conversions.

The larger the precision, the more bits you pick up in the long division to get the fraction. If the precision is too large, so that the denominator shifted by the precision bits exceeds the 2^32 limit, the result will be incorrect. For example, if the denominator is 60 (such as for the VxWorks sysClkRate), precision_bits larger than 27 exceed the limit and produce an incorrect result. In general:

maximum precision_bits = 32 - (int)log2(denominator_per_sec),

where log2(x) can be calculated by:

    int log2answer = 0;
    while (x >>= 1) {1
        log2answer++;
    }

For 60 (sysClkRateGet()), this would be 27. For gettimeofday() with microsec resolution, this would be 12.

But in practice, that kind of precision is not necessary nor desirable since the conversion would be slower. Instead, the precision is only important relative to the denominator. If your clock frequency is low (e.g., 60 Hz), you only have 16.6 ms resolution anyway. If you are within a tenth of your clock resolution, that is probably good enough.

If we generalized too much and tried to handle nanosec resolution "ticks," we could not guarantee adequate accuracy for all ranges. So internally, we selected a reasonable number that gives us adequate accuracy over large ranges. We wanted a precision that will work well up to 1e6 tick rate (thinking about UNIX gettimeofday()); 7 passed the test.

#define OSAPI_NtpTime_from_fraction (   time,
  numerator,
  denominator_per_sec 
)
Value:
OSAPI_NtpTime_from_fraction_bits((time), (numerator), (denominator_per_sec), \

Macro to convert numerator/denom_per_sec into NTP time.

Parameters:
timestruct OSAPI_NtpTime to contain the result. The existing content of time does not affect the result.
numeratorMay be larger than denominator. Since this is a macro and the numerator is evaluated multiple times, you should not specify things like (i++).
denominator_per_secDenominator. Physically, this means ticks per sec. Since this is a macro and the denominator is evaluated multiple times, you should not specify things like (i++).
#define OSAPI_NtpTime_to_fraction (   numerator,
  denominator_per_sec,
  time 
)
Value:
OSAPI_NtpTime_to_fraction_bits((numerator), (denominator_per_sec), (time), \

Transforms from struct OSAPI_NtpTime to any integral fraction of a second without using floating point operations.

Parameters:
numeratorRTI_UINT32 where to put the result of the conversion.
denominator_per_secThe number of units of the fraction contained in a second. For example, this should be 1000 to convert to milliseconds, or 60 if you are using the default VxWorks clock rate.
timestruct OSAPI_NtpTime to unpack

The algoritm is based on the observation that the time.frac looked at as a sequence of bits: b[1], b[2], b[3], ... represents the following expansion:

time_in_sec = b[1]*1/2 + b[1]*1/4 +...+ b[2]*1/8 = Sum{i=1..32} b[i]*1/2^i

Since we want to obtain the time in units of which there are denominator_per_sec units in a second, the arithmetic is:

time_in_units = denominator_per_sec*time_in_sec = denominator_per_sec*time.sec+denominator_per_sec*time.frac

And denominator_per_sec*time.frac = Sum{i=1..32} b[i]*(denominator_per_sec/2^i)

The key here is that b[i] is easily computed as (1<<31)>>(i-1) and (denominator_per_sec/2^i) is easily computed as denominator_per_sec>>i.

Note that each time we compute (denominator_per_sec/2^i) to add it, we may be off by one unit. Therefore, at the end of the computation we may be off by log2(denominator_per_sec) units, which means we should in fact perform each step with an accuracy of log2(2*denominator_per_sec) greater. In other words, we should use units a factor log2(2*denominator_per_sec) greater than the ones we require at the end of the conversion.

Another key observation is that the computation can end as soon as (denominator_per_sec<<OSAPI_NTP_TIME_PRECISION_BITS_DEFAULT)>>i becomes zero because that means what is left has a significance of less than one unit>>OSAPI_NTP_TIME_PRECISION_BITS_DEFAULT. This will give a conversion that is strictly smaller than the NTP timestamp. For example, for millisecond conversion log2(1000) = 10, we will do 10 operations so we need a precision of 1/20 or 5 bits (4 bits gives 1/16, 5 gives 1/32).

The final operation: (precision_units + (1<<OSAPI_NTP_TIME_PRECISION_BITS_DEFAULT-1))>> OSAPI_NTP_TIME_PRECISION_BITS_DEFAULT; makes sure that the integer division by 2^(OSAPI_NTP_TIME_PRECISION_BITS_DEFAULT) is rounded off to the closest number.

#define OSAPI_NtpTime_compare (   time1,
  time2 
)
Value:
((((time1)->sec) > ((time2)->sec)) ? 1 : \
((((time1)->sec) < ((time2)->sec)) ? -1 : \
((((time1)->frac) > ((time2)->frac)) ? 1 : \
((((time1)->frac) < ((time2)->frac)) ? -1 : 0))))

Compare two OSAPI_NtpTimes.

Parameters:
time1struct OSAPI_NtpTime, NOT NULL.
time2struct OSAPI_NtpTime, NOT NULL.
Returns:
If time1 > time2, return 1. If time1 < time2, return -1. If time1 == time2, return 0.
#define OSAPI_NtpTime_is_infinite (   time)
Value:
(((time)->sec == OSAPI_NTP_TIME_SEC_MAX) ? \
RTI_TRUE : RTI_FALSE)

A NULL struct OSAPI_NtpTime pointer is considered infinity. This is consistent with the concept of infinite time on UNIX systems.

In addition, if the seconds field equals OSAPI_NTP_TIME_SEC_MAX, the time value is also considered infinite.

Parameters:
timePointer to RTITime.
Returns:
RTI_TRUE if time is infinite, RTI_FALSE otherwise.
#define OSAPI_NtpTime_add (   answer,
  t1,
  t2 
)
Value:
{\
(answer)->sec = (t1)->sec + (t2)->sec; \
(answer)->frac = (t1)->frac + (t2)->frac; \
if (((answer)->frac < (t1)->frac) || ((answer)->frac < (t2)->frac)) { \
(answer)->sec++; \
} \
}

answer = t1 + t2.

This macro does not check for overflow.

Parameters:
answerstruct OSAPI_NtpTime
t1struct OSAPI_NtpTime
t2struct OSAPI_NtpTime
#define OSAPI_NtpTime_subtract (   answer,
  t1,
  t2 
)
Value:
{\
*(answer) = *(t1); \
} else if (OSAPI_NtpTime_is_infinite(t2)) { \
(answer)->sec = 0; \
(answer)->frac = 0; \
} else { \
(answer)->sec = (t1)->sec - (t2)->sec; \
(answer)->frac = (t1)->frac - (t2)->frac; \
if ((answer)->frac > (t1)->frac) { \
(answer)->sec--; \
} \
}\
}

answer = t1 - t2.

Parameters:
answerstruct OSAPI_NtpTime
t1struct OSAPI_NtpTime`
t2struct OSAPI_NtpTime
#define OSAPI_NtpTime_left_shift (   answer,
  time,
  shift 
)
Value:
{\
register RTI_UINT32 mask = 0xffffffff; \
if (shift) { \
(answer)->sec = ((time)->sec)<<shift; \
mask = mask<<(32 - shift); \
mask &= (time)->frac; \
mask = mask>>(32 - shift); \
(answer)->sec |= mask; \
(answer)->frac = ((time)->frac)<<shift; \
} \
else { \
answer = time; \
} \
}

answer = time << shift.

To use this macro for multiplying by num, shift can be calculated as log10(num)/log10(2).

Parameters:
answerstruct OSAPI_NtpTime
timestruct OSAPI_NtpTime
shiftint
#define OSAPI_NtpTime_right_shift (   answer,
  time,
  shift 
)
Value:
{\
register RTI_UINT32 mask = 0xffffffff; \
if (shift) { \
(answer)->frac = ((time)->frac)>>shift; \
mask = mask>>(32 - shift); \
mask &= (time)->sec; \
mask = mask<<(32 - shift); \
(answer)->frac |= mask; \
(answer)->sec = ((time)->sec)>>shift; \
} \
else { \
answer = time; \
} \
}

answer = time >> shift.

To use this macro for dividing by num, shift can be calculated as log10(num)/log10(2).

Parameters:
answerstruct OSAPI_NtpTime
timestruct OSAPI_NtpTime
shiftint
#define OSAPI_NtpTime_increment (   answer,
  time 
)
Value:
{ \
register RTI_UINT32 currentFrac = (answer)->frac; \
(answer)->sec += (time)->sec; \
(answer)->frac += (time)->frac; \
if (((answer)->frac < (time)->frac) || ((answer)->frac < currentFrac)) { \
(answer)->sec++; \
} \
}

answer += time.

This macro does not check for overflow.

Parameters:
answerstruct OSAPI_NtpTime
timestruct OSAPI_NtpTime
#define OSAPI_NtpTime_decrement (   answer,
  time 
)
Value:
{ \
register RTI_UINT32 currentFrac = (answer)->frac; \
(answer)->sec -= (time)->sec; \
(answer)->frac -= (time)->frac; \
if (((answer)->frac > currentFrac)) { (answer)->sec--; } \
}

Decrement one struct OSAPI_NtpTime value by another struct OSAPI_NtpTime value.

Precondition: Postcondition: answer -= time.

Parameters:
answerstruct OSAPI_NtpTime
timestruct OSAPI_NtpTime
#define OSAPI_NtpTime_increment_infinitesimally (   time)    ((++((time)->frac)) == 0) ? ++(time)->sec : 0

time = time + 1 fraction (~200 picoseconds).

This macro does not check for overflow, so time cannot be infinite.

Parameters:
time
Returns:
NO RETURN VALUE => do NOT evaluate this expression; simply call it.
#define OSAPI_NtpTime_is_zero (   time)
Value:
(((time) && (time)->sec==0 && \
(time)->frac==0) ? \
RTI_TRUE : RTI_FALSE)

Checks if the time structure represents zero time. Zero time may be useful when getting the sign of the time quantity.

Parameters:
timePointer to struct OSAPI_NtpTime. Must not be NULL.
Returns:
RTI_TRUE if time is zero, RTI_FALSE otherwise.
#define OSAPI_NTP_TIME_ZERO   {0,0}

Zero time.

This global variable is for convenience. It allows you to see if a RTITime variable is negative or positive by comparing against this.

See also:
RtiTimeCompare
#define OSAPI_NTP_TIME_MAX   {OSAPI_NTP_TIME_SEC_MAX,OSAPI_NTP_TIME_FRAC_MAX}

Represents the maximum timevalue that can be represented using the NTP time format. For all practical purposes, it can be considered equivalent to infinity.

#define OSAPI_NTP_TIME_NSEC_PER_SEC   (1000000000)

The number of nanoseconds per second. 1e9.

See also:
RtiTimePack RtiTimeUnpack
#define OSAPI_NTP_TIME_USEC_PER_SEC   (1000000)

The number of microseconds per second. 1e6.

See also:
RtiTimePack RtiTimeUnpack
#define OSAPI_NTP_TIME_MSEC_PER_SEC   (1000)

The number of milliseconds per second. 1e3.

See also:
RtiTimePack RtiTimeUnpack
#define OSAPI_NTP_TIME_NSEC_PER_USEC   (1000)

The number of microseconds per milliseconds. 1e3.

See also:
RtiTimePack RtiTimeUnpack
#define OSAPI_NTP_TIME_USEC_PER_MSEC   (1000)

The number of microseconds per milliseconds. 1e3.

See also:
RtiTimePack RtiTimeUnpack
#define OSAPI_NTP_TIME_SEC_PER_SEC   (1)

The number of seconds per second. 1.

See also:
RtiTimePack RtiTimeUnpack
#define OSAPI_NTP_TIME_NSEC_PER_MSEC   (1000000)

The number of nano seconds per milli second. 1e6.

See also:
RtiTimePack RtiTimeUnpack

Typedef Documentation

typedef struct OSAPI_NtpTime OSAPI_NtpTime

NtpTime API.

NTP Time representation.

Expresses time in NTP format. The second field is simply an integer expressing seconds. The fraction field expresses 1/2^32 of a second. We strongly urge customers to use our provided macros to convert this format to and from human readable form.

OSAPI_NtpTime_init must be called before OSAPI_NtpTime_get. Creating a domain has the side-effect of calling OSAPI_NtpTime_init.

Example:

The following is a simple example on how to prepare a struct OSAPI_NtpTime structure to be 1.5 seconds.

     struct OSAPI_NtpTime ntpTime;

     OSAPI_NtpTime_packFromMillisec(ntpTime, 1, 500);
See also:
OSAPI_NtpTime_packFromMillisec OSAPI_NtpTime_packFromMicrosec
OSAPI_NtpTime_packFromNanosec
OSAPI_NtpTime_unpackFromMillisec OSAPI_NtpTime_unpackFromMicrosec
OSAPI_NtpTime_unpackFromNanosec

RTI Connext Micro Version 2.4.1.0 Copyright © Thu Nov 20 2014 Real-Time Innovations, Inc