INtime SDK Help
Time management
INtime SDK v7.1 > About INtime > INtime Kernel > Time management

Overview

INtime software defines a value called "system time" which counts seconds and microseconds since the system epoch (January 1, 1978). This value is driven from the system hardware timer which is also used to synchronize threads in the kernel.

Time values are expressed in two structures:

TIMEVALUE is a structure which consists of a count of seconds and microseconds

SYSTEMTIME is a structure which specifies a date and time using individual members for year, month, day, weekday, hour minute second and microsecond.

INtime software provides time management calls that allow threads to create alarms and to sleep for a specified amount of time.

An alarm is an object which is signaled when a pre-determined time interval has expired. The alarm event mode may be single-shot or repeatable.

The kernel's RT clock is a counter that the kernel uses to keep track of the number of low-level ticks (kernel clock) that have occurred. When the kernel is initialized, the count is set to 0 (zero). The period of the low-level ticks is configurable via the INtime for Windows Configuration or the INtime Distributed RTOS Configuration and you can read the current configuration using CopyRtSystemInfo.

Clock granularity

High-level RT system calls have a fixed wait-time granularity of 10 milliseconds (High-level ticks). The value specified for the time period is truncated to the nearest multiple 10-millisecond value. For example a value specified as 9 will be truncated to 0; a value of 11 will be truncated to 10.

Low-level (kernel) system calls have a configurable wait-time granularity that can be selected from the following options:

Kernel tick

   10 milliseconds
    5 milliseconds
    2 milliseconds
    1 millisecond
  500 microseconds (default)
  250 microseconds
  200 microseconds
  125 microseconds
  100 microseconds
   50 microseconds

Other clock intervals may be configured manually. Contact TenAsys Support if you would like information about this feature and its implications.

Selecting the low-level ticks (kernel) is an important setting for the system performance. Every time the low-level ticks occur, an interrupt is generated, the scheduler is called and some housekeeping is performed. It is best to reduce this load as much as possible. The shortest timing period in the application determines the best setting. If e.g. the application needs to respond on a 500 microseconds interval on a fieldbus, this is the preferred kernel tick setting. Choosing a shorter time, does not make the system faster or better reacting. Most threads are called outside the low-level ticks anyway, as semaphores or mailboxes just suspend one thread and signal another thread, which awakes as soon as possible based on priority (without waiting for the next low-level tick to arrive).

System time

System time is the number of elapsed seconds and microseconds since the INtime epoch. System time is managed by a microseconds counter driven by the system timer hardware. It may be read and set in different formats. Setting the system time changes only the software counter, not the timer hardware.

Read the system time using either GetRtSystemTime or GetRtSystemTimeAsTimeValue. Set the time using SetRtSystemTime or SetRtSystemTimeAsTimeValue.

The rate at which the counter is incremented may be adjusted (for example to synchronize the system time with an external clock source) using the SetRtSystemTimeAdjustment call.

Note: the system time value is not subject to time zone adjustments. On INtime for Windows the C library treats the system time value as UTC, and makes adjustments according to the value of the TZ environment variable for those calls which use local time. On INtime Distributed RTOS systems there is a configuration where the system time can be assumed to be local time instead of UTC.

System time synchronization

INtime for Windows is configured by default to synchronize the kernel system time with the Windows system time. A Windows service (INtime Clock Synchronization Service) manages this synchronization. The interval at which the system time is synchronized is configurable in the Kernel parameters and the default is every 300 seconds.

At kernel start-up, the INtime time of day (TOD) is set to match the Windows TOD. Thereafter, at each configured TOD update interval the INtime TOD is adjusted gradually to match the Windows TOD. You can also call the SyncLocalRtClock() function to start the adjustment process before the TOD update interval. A configured adjustment value is added to (or subtracted from) the INtime TOD at each system timer tick until the entire adjustment is made. If there is a large difference between the two clocks, it can take a while until they match.

There are options for the Advanced configuration tab of the INtime configuration tool to control how the time is adjusted. If you wish to change the default values you may need to add the section before adding the values.

Section: [ADJTIME]

BIGTHRESH
Range: 1-0xffffffff
Gives the threshold (in microseconds) between big adjustments and small adjustments. The default is 1000000 (1 second). So if the total delta to adjust the TOD is more than 1 second, BIGADJ microseconds are added to (or subtracted from) the TOD at each kernel clock tick until the entire adjustment is made. Otherwise, TICKADJ microseconds are used.
TICKADJ
Range: 1-0xffffffff
Gives the amount (in microseconds) to adjust the TOD at each system timer tick for total adjustments that are smaller or equal to BIGTHRESH. The default is (kernel tick period)/25.
BIGADJ
Range: 1-0xffffffff
Gives the amount (in microseconds) to adjust the TOD at each system timer tick for total adjustments that are more than BIGTHRESH. The default is (kernel tick period)/4.

Section: [CLKSYNC]

ATTHRESH
Range: 1-0xffffffff
Adjustments greater than or equal to the configured value cause the INtime TOD to be set immediately to the current Windows TOD; smaller adjustments are applied gradually, according to the ADJTIME configuration. Default is 5 minutes (300000000 microseconds).

Note that there is not much sanity checking done on the values provided for these parameters, so it is possible to configure values that may have unexpected/catastrophic results. For example, making BIGADJ > the system timer tick period (e.g., larger than 500 microseconds) can have the result that the INtime TOD moves backward between consecutive calls to read the time.

INtime Distributed RTOS systems initially synchronize with the system's RTC (battery clock) at startup, and do not perform any further synchronization by default. There is an optional SNTP client which may be configured to synchronize with an external server.

If you wish to perform your own synchronization then you must disable the Clock Synchronization Service and use the SetRtSystemTimeAdjustment call to make any adjustments.

Using alarms

The kernel lets you create alarm events to simulate timer interrupts. The system signals the alarm event object at which a thread you have written waits.

Two kinds of alarm events exist:

Create an alarm with the CreateRtAlarm system call and delete it with the DeleteRtAlarm system call. To create an alarm specify:

Use WaitForRtAlarm within a thread to signal the thread whenever the alarm's time expires.

After a thread calls the DeleteRtAlarm system call, the alarm object will no longer be signaled. Alarms can be deleted at any time. This means that deleting an alarm does not have to be synchronized with the expiration of the alarm.

The ResetRtAlarm system call resets an alarm, returning it to its initial state. Both single shot and repetitive alarms can be reset. Regardless of whether the alarm's time limit has expired, resetting an alarm returns it to its creation state and starts it running as if it were just created. Resetting a single shot alarm after it has gone off is equivalent to creating the alarm again.

Using sleep

The kernel enables threads to sleep for a specified time, using the RtSleep or RtSleepEx system call. The amount of time the thread will be in the asleep state can vary from no time to forever. If the specified time is NO_WAIT, the thread will not sleep. A time limit of NO_WAIT gives the processor to another thread of equal priority, if one exists.

WAIT_FOREVER means the thread will never wake up. When a thread sleeps forever, it is effectively deleted, but its memory is not released. If a thread has completed its assigned functions, then delete it or suspend it rather than doing a sleep forever.

Using the INtime timestamp counter

INtime provides a timestamp counter facility which is accessible from all nodes, and also Windows via NTX. The best possible source is automatically configured in order to provide a counter which is coordinated between the different nodes (the sources run at exactly the same frequency) and also if possible synchronized (in other words returns the same value from each node at a given instant). Where possible the source used is the system HPET, but if this is not available the CPU Time Stamp Counter (TSC) is used.

The system call GetRtTimestampInfo returns both the period of the configured counter, and flags indicating whether the source is coordinated and synchronized. The call GetRtTimestampCounter returns the value of the selected counter.

System timer hardware synchronization

Sometimes it is desirable to synchronize the INtime system timer with an external timer source. Cases might include synchronization with a timestamp in an Ethernet packet in order to synchronize the application's cycle time to the source precisely.

Note: this is not the same as synchronizing the INtime wallclock (system time) with an external source. In that case the time of day provided by the system is kept in sync with an external source, irrespective of the local system timer rate. This type of synchronization can be achieved with the existing interfaces, such as SetRtSystemTimeAdjustment, or adjtime in the C library.

Two APIs are provided for this function. GetRtSystemTimerValues provides details of the current system clock configuration including the period of the base interrupt signal, and the reload value which is used to program the hardware clock. This last value is in arbitrary units and is provided to enable the programmer to determine the size of any increment to make to the clock. AdjustRtSystemTimer provides an increment to be applied to the reload value of the system timer.

Access to system battery clock

The PC system CMOS clock (or "RTC") hardware is accessible from an application running on INtime Distributed RTOS. It is not accessible from an application running on INtime for Windows since in that case Windows is in control of the CMOS clock hardware.

The two APIs are provided to read or write the clock hardware. GetRtHardwareClock may be read for use when synchronizing the system timer, for example. SetRtHardwareClock is intended for use during the installation and initial configuration of a system only.

Warning: Changing the system battery clock after installation may cause license failure.

System calls

This section lists common operations related to time and alarms, and the kernel system calls that do the operations:

To . . . Use this system call . . .
Return the current system time in a SYSTEMTIME structure GetRtSystemTime
Set the system time from a SYSTEMTIME structure SetRtSystemTime
Return the current system time in a TIMEVALUE structure GetRtSystemTimeAsTimeValue
Set the system time from a TIMEVALUE structure SetRtSystemTimeAsTimeValue
Return the current time adjustment value GetRtSystemTimeAdjustment
Set the system time adjustment SetRtSystemTimeAdjustment
Converts a SYSTEMTIME value to a TIMEVALUE value SystemTimeToTimeValue
Convert a TIMEVALUE value to a SYSTEMTIME value TimeValueToSystemTime
Compare two TIMEVALUE values CompareRtTimeValue
Return a TIMEVALUE of the number of microseconds elapsed since the system was started GetRtRunTime
Create an alarm CreateRtAlarm
Delete an alarm DeleteRtAlarm
Reset an alarm ResetRtAlarm
Wait on an alarm WaitForRtAlarm
Get elapsed time as number of system timer ticks. knGetKernelTime
Reset the time as number of system timer ticks. knSetKernelTime
Put a thread to sleep RtSleep, RtSleepEx
Get the timestamp counter information GetRtTimestampInfo, ntxGetRtTimestampInfo
Get the timestamp counter value GetRtTimestampCounter, ntxGetRtTimestampCounter
Get CPU timestamp counter and frequency QueryRtPerformanceCounterQueryRtPerformanceFrequency
Read the system CMOS clock ("RTC") GetRtHardwareClock
Set the system CMOS clock ("RTC") SetRtHardwareClock
Read the system hardware timer details GetRtSystemTimerValues
Make an adjustment to the system hardware timer AdjustRtSystemTimer
Synchronize the time of day clock to an external source. SyncLocalRtClock

 

See Also

Structures

C library