PXI, Desktop ETS, FieldPoint, Industrial Controller, Smart Camera, and Linux Real-Time targets do not natively support SNTP synchronization. This process only applies to CompactRIO controllers running the VxWorks operating system (OS). To verify which OS is running on your controller, please reference
Real-Time Controllers and Real-Time Operating System Compatibility.
As of LabVIEW Real-Time 8.6, CompactRIO real-time controllers using the VxWorks operating system can be configured to synchronize to SNTP servers.
To configure the controller to synchronize to an SNTP server, go through the following steps:
1. FTP the ni-rt.ini file from the controller to your Windows machine.
2. Add the following lines to the ni-rt.ini file of the controller in the time sync section at the bottom.
[TIME SYNC]
source_priority=sntp;rtc;
source.sntp.enable=true
source.sntp.address=x.x.x.x
source.sntp.interval=60
source.sntp.port=123
source.sntp.verbose=false
source.sntp.log=false
3. FTP the modified ni-rt.ini file back to the controller. After updating the ni-rt.ini file and rebooting, the cRIO controller will automatically implement synchronization to the SNTP server.
The following table describes the .ini tokens:
Token | Type | Default | Importance | Description |
---|
source_priority | string | sntp | REQUIRED | Lists the relative priority of installed time sync plug-ins. For cRIO, the possible options are rtc, dio, and sntp. |
source.sntp.enable | bool | false | REQUIRED | Set to true to enable the SNTP time sync plug-in. Set to false to disable. |
source.sntp.address | string | 0.0.0.0 | REQUIRED | Specifies the IPv4 address of the SNTP time server. Choose a server in your region from the NIST Internet Time Service Clock link below. Use "." delimited address. Using a named address, like pool.ntp.org does not work at this time. |
source.sntp.interval | int | 60 | Recommended | By default the SNTP client driver sleeps for an interval between successive time server polls. Set a new delay, specified in seconds, to adjust the interval. |
source.sntp.port | int | 123 | Optional | By default SNTP uses a known port to contact the time server. Set a new port number if the time server is on a non-standard port. |
source.sntp.verbose | bool | false | Optional | By default SNTP client driver errors are silently discarded. Set to true to enable display of verbose errors in the console out. |
source.sntp.log | bool | false | Optional | Set to true to log timestamps to a file. This should only be used for debugging purposes. When set to true, the log will be located under ni-rt\system\ts_sntp_log.txt |
Additional Information
Example of the ts_sntp_log.txt (64-bit Hex):
currentLocalTimeNS, frequencyHz, t1_raw, t2_ns, t3_ns, t4_raw |
30744de63d52117c: 98989929.000000, 000000004b7deac0, 30744e740a609a99, 30744e740a60ee36, 000000004b90fef7 |
Parameter | Definition |
currentLocalTimeNS | Local time on the cRIO |
frequencyHz | Clock processor frequency |
t1_raw | Originate timestamp, time request sent by client |
t2_ns | Receive timestamp, time request received by server |
t3_ns | Transmit timestamp, time reply sent by server |
t4_raw | Destination timestamp, time reply received by client |
If we convert the timestamps from the above example to decimal, we get:
t1_raw = 1,266,543,296
t2_ns = 3,491,501,871,416,253,081
t3_ns = 3,491,501,871,416,274,486
t4_raw = 1,267,793,655
However, t1_raw and t4_raw aren't that useful to us. Instead, we need to convert each of them to a duration since the controller was last booted:
t1_raw = 0x4b7deac0 = 1,266,543,296 ticks
t1_duration_since_boot = (tick count * nanoseconds per second / frequency) = (1,266,543,296 * 1e9 / 98,989,929) = 12,794,668,192 nanoseconds (~12.7 seconds)
t4_duration = 12,807,299,366 ns (~12.8 seconds)
Now we can calculate a meaningful value for t when this exchange occurred:
t = ((t2 - t1) + (t3 - t4)) / 2
t = ((3491501871416253081-12794668192) + (3491501871416274486-12807299366)) / 2
t = 3,491,501,858,615,279,616 ns
This value gets saved in a variable in software. When our RT controller needs to know what time it is, it reads the current tick count, converts that into a duration (tick * 1e9 / freq), and then adds this t value. This value represents the difference between a local counter and the NTP server's counter, but it does not represent the amount of error in our local timestamps (our offset from reference).
Calculating our instantaneous offset from the NTP time reference with this data isn't really possible. What we can do, however, is look at how the t value changes over time. The difference between a new t value and the previous t value will tell us how much our local concept of time has drifted away from the NTP master during the previous sync interval. This can give us a rough idea of our offset from reference.
Additionally, the following two methods can be used to evaluate server performance:
1. Calculate the roundtrip delay d and local clock offset t:
d = (t4_raw - t1_raw) - (t2_ns - t3_ns)
t = ((t2_ns - t1_raw) + (t3_ns - t4_raw)) / 2
2. Compare local time on the cRIO to the server time with the following equation:
(t2_ns + t3_ns) / 2
The SNTP is a simplified subset of the Network Time Protocol (NTP). Additional options for other Time Servers can be found in the related links section below.
SNTP synchronization does a large correction of the date-time on boot. After boot, it adjusts the processor clock to account for drift. The algorithm has an error tolerance but if you exceed that tolerance (i.e. if you are too far out of sync) it will stop trying to adjust the processor clock to synchronize. Calling the Set Date & Time VI typically causes the clock to move beyond the algorithm error tolerance.