Skip to main content

Overview

A pure Python interface to the NTP shared memory segment with no external dependencies.

The only platform-dependent part of this library is the SHM_CREAT constant, which seems to always be the octal value of 01000 (Linux and BSDs). Technically the size of time_t is also platform-dependent, but it's 2021 and this should be 64 bit everywhere.

Prerequisites

Python: 3.7+

OSs: Posix-compliant with the System V shared memory interface.

This uses ctypes for direct access to memory and shared memory routines. This will dynamically load the system's C library to access shmget() and shmat() functions.

Usage

NTP Shared Memory

The NtpShm class wraps up access to the NTP shared memory segments. See the NTP documentation for information on the contents of this memory and how to safely access it.

Example use:

from ntp_shm import NtpShm

seg = NtpShm(segment=0)

# Access copies of the memory segment (ShmTime) through read()/write()
shm_time = seg.read()
shm_time.count += 1
shm_time.clock_time_sec = 42
# ...
seg.write(shm_time)

# Dynamic, direct access (by ref) through .ref
shm_time = seg.ref  # Or just use seg.ref directly
shm_time.count += 1
shm_time.clock_time_sec = 42
# ...

The ShmTime object is a ctypes structure with a few extra properties for convenience, and with fields renamed slightly to be more pythonic. The convenience properties can be used to set or get the clock or receive times using datetime objects or integer time in nanoseconds.

>>> shm_time = seg.ref
>>> seg.ref.receive_dt
datetime.datetime(2021, 9, 6, 13, 45, 3, 495830, tzinfo=datetime.timezone.utc)
>>> seg.ref.receive_dt
datetime.datetime(2021, 9, 6, 13, 45, 4, 440210, tzinfo=datetime.timezone.utc)
>>> shm_time.clock_ns
1630935919000000000

Keep in mind that the datetime representation is only accurate to the microsecond.

Important: Direct access to the shared memory segment suffers from race conditions. Since the time values are split up across multiple fields, these may be modified in between field reads leading to consumers reading corrupted values.

The NTP documentation (above) specifies two different methods of updating and reading from the shared memory segment to avoid this issue. Writing via mode 1 is implemented in the ShmTime.update() method. This can be used to update the clock and receive times:

from ntp_shm import util, NtpShm

seg = NtpShm()

clock_time_ns = some_function_that_gives_integer_nanoseconds()
receive_time_ns = util.datetime_to_ns(datetime.datetime.now())

seg.update(clock_time_ns, receive_time_ns)

Since Python lacks memory barriers or cache synchronization controls, its still not 100% guaranteed that the update() method will be issue free.

NTP Bridge

Included is a utility command: ntp-shm bridge. This acts as a very basic NMEA0183 bridge to NTP shared memory. It reads lines from a file input, looking for and parsing valid GPRMC NMEA sentences. Valid times, after a small holdoff to allow for stabilization, are passed to the NTP shared memory segment.

The NMEA sentences must come from a file-like device, such as a character device or pipe (stdin). For GPSs connected to a serial tty device, use stty to configure the device for direct access. Alternatively, use one of many applications to handle the serial interface and pipe the output to ntp-shm bridge.

Example tty setup for raw access (on FreeBSD).

stty -f /dev/ttyu1.init raw 9600

Test the tty configuration using cat /dev/ttyu1. The output should be smooth, without extra blank lines or non-printable characters.

To bridge the NMEA data on ttyu1 to segment 0:

ntp-shm bridge -p /dev/ttyu1 -s 0

To create a persistent process, consider using daemon (FreeBSD) or daemonize (Linux) and your system's service manager.

Installation

From pypi:

pip install ntp-shm

From your local checkout:

pip install [--user] .

or

python setup.py install [--user]

Metadata

Release files for ntp-shm 2.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ntp-shm 2.0.2
File Size Uploaded
ntp-shm-2.0.2.tar.gz 13.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ntp-shm 2.0.2
File Interpreter ABI Platform
ntp_shm-2.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 24.6 kB

Release files / ntp-shm-2.0.2.tar.gz

Download URL ntp-shm-2.0.2.tar.gz
Size 13.7 kB
Tags Source
SHA-256 checksum
How to use checksums
74c9344d058bfd36cedd5ae0fb8033c4926e0a8c55c722cf82491c08c19e6d75
BLAKE2b-256 checksum
How to use checksums
84a42117cb5d4a17caea67cde98e2f1899eb2070716f4a6aa2ad1d470de94d5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.6

Release files / ntp_shm-2.0.2-py3-none-any.whl

Download URL ntp_shm-2.0.2-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b18657abf946f41d71527d5200af3c9d7c6ee2a3b4c18437041f2df2ca585b91
BLAKE2b-256 checksum
How to use checksums
4225c86941823d3ce6b3222050f8b2d5a7aefee3dbfb67a67484ad6f6081cac4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.6

Release history Release notifications | RSS feed

This release

2.0.2 This release

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.6.0

2 release files

1.5.0

1 release file

1.4.0

2 release files

1.2.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page