kb:time_sync:ntp:ntp_for_windows:using_pps_signals_on_windows

Using PPS Signals on Windows

This information is also available at the NTP support wiki at:


A couple of years ago Dave Hart made the serialpps.sys driver available, which was based on a copy of the serial port example driver shipped with the Windows SDK, and extended the driver to support the standard PPS API which is also available on many Unix-like systems. In addition there was a serialpps-ppsapi-provider.dll which could be used to let ntpd fetch PPS timestamps from the kernel driver:


At least the 64-bit versions of Windows released thereafter (Vista and newer) require kernel drivers to be cryptographically signed, so Meinberg picked up Dave Hart's code and signed the kernel drivers with their key. The original download location of the resulting binaries isn't reachable anymore, so a copy of the .zip file with the signed driver is available via the Meinberg web page:


So folks who want to play with it can do it. This sys/dll package was never included in the installer/setup program. The .zip file contains an install.bat script which copies the .sys file to its final location and prints some hints, but it doesn't copy the associated DLL to some predefined directory, so this was probably the original reason why the DLL path has to be specified via an environment variable, or with ntpd 4.2.8p10 or later using a registry key.

Many more hints on using this driver can be found on David J. Taylor's web page:


These days PCs and laptops often don't provide a real serial port with a physical UART chip, so maybe this approach can't be used on these machines.


To work around the problem that there is no physical UART chip there has been something in ntpd that was known (alas, not widely known) as the 'PPS hack': Since ntpd anyway had to monitor the serial line for what Windows calls COMM events, it also checked for level changes of the DCD line and used the time stamp of this change to supplant the receive time stamp for the next line of text. (E.g. the next NMEA record.) This works in user mode and needs no special driver, and it works for every serial interface known to Windows, but it gives reliable results only under tight constraints. (Having more than one NMEA record in the output cycle and selecting not the first after the PPS pulse completely defeats this!)

Whether the PPS Hack is to be used, or not, could be configured via an environment variable.


The loopback-ppsapi-provider.dll came into existence as a means to get around the limitations of serialpps.sys without requiring a kernel mode driver. A kernel mode driver can (but not necessarily will) provide time stamps with less jitter than any user mode application, but loopback-ppsapi-provider.dll seems to do a very decent job here. In case you wonder about the name: This provider loops back into ntpd to tap into information already there.

This DLL is part of current versions of the normal NTP source code distribution.


PPS support configuration under Windows means specifying the PPS API provider DLL(s) to be used.

The original approach was to set up some environment variables to configure the way the PPS slopes were to be handled. However, specifying a DLL name in an evironment was found to be a potential security risk (see NTP bug 3384), so with ntpd 4.2.8p10 and later the path to the PPS provider DLL to be used should preferably be specified in the Windows registry.

When the instsrv.exe utility is used to install the NTP service then a registry key with loopback_pps_api_provider.dll is created automatically.

To set up the key manually, run the Windows regedit utility, and open this registry path:

HkeyLocalMachine\SYSTEM\CurrentControlSet\services\NTP

Then create a new key as multipart string, with the name PPSProviders, and set the contents to loopback_pps_api_provider.dll or whichever PPS API provider you prefer.


This original approach can be insecure, so if ntpd 4.2.8p10 or newer is installed then preferably a registry key should be set up instead to specify the PPS API provider(s) to be used. See also the notes below.

There are two environment variables involved, and since ntpd is meant to be run as Windows service, these must be SYSTEM variables:

  • PPSAPI_DLLS is a ';'-separated list of file names that should be tried in sequence to provide a PPS API for a device. For maximum interoperability between different versions of Windows the files should be given with absolute path, using standard Windows conventions (that is, use '\' as path separator).
  • PPSAPI_HACK should be a boolean value (Yes/No/True/False/0/1) or be left unset, and controls the the PPS-hack operation.

When it comes to controlling the PPS hack, there is some dependency between those two settings. The decision is based on the principle of least surprise:

  • If neither PPSAPI_DLLS nor PPSAPI_HACK is set in the environment, the PPS hack works as it has always done.
  • If only PPSAPI_DLLS is set (and not empty) it disables the PPS hack, assuming that a better way of handling PPS signals is provided. (The interaction between the PPS API and the PPS hack is somewhat tricky. It's better to avoid this area where dragons are roaming unless you feel really adventurous.)
  • The environment variable PPSAPI_HACK takes precedence over PPSAPI_DLLS: if it is set to Y[es], T[rue] or 1 it enables the PPS hack independently of any setting of PPSAPI_DLLS; any other value disables the PPS hack unconditionally.

So the cleanest setting that does not require kernel mode support is to have the following in your system environment:

PPSAPI_DLLS=C:\your\path\to\loopback-ppsapi-provider.dll
PPSAPI_HACK=No 

Notes:

  • In ntpd 4.2.8p10 and newer the environment variables are only checked for compatibility reasons, if no registry key can be found.
  • If the DLL name is specified as file name only, without a path, then the DLL is assumed in the same directory as ntpd.exe.
  • If the Meinberg installer is used then the loopback-ppsapi-provider.dll is installed in the NTP/bin directory where also ntpd.exe and the openSSL DLL normally reside.
  • Please note there is a bug in ntpd 4.2.8p10 where the DLL name retrieved from the environment variable is not properly terminated, so garbage characters may be appended to the DLL name, and thus the DLL file may not be found. See NTP bug 3402 http://bugs.ntp.org/show_bug.cgi?id=3402 for details and a workaround.

Martin Burnicki martin.burnicki@meinberg.de, last updated 2023-12-15

  • kb/time_sync/ntp/ntp_for_windows/using_pps_signals_on_windows.txt
  • Last modified: 2023-12-15 15:04
  • by 127.0.0.1