Precision Timing

The precision timing subsystem provides a small set of reusable mechanisms for PTP, gPTP, and other users that control high-resolution clocks. Enable it with CONFIG_PRECISION_TIMING.

Note

The API is at experimental maturity and may still change. A protocol does not change maturity by using this subsystem.

The subsystem deliberately does not implement synchronization policy. PTP and gPTP continue to own their protocol state machines, clock selection, step thresholds, sample acceptance, lock detection, source-loss handling, and diagnostics.

Precision time

precision_time_t is a signed 64-bit nanosecond value. Checked addition and subtraction helpers report overflow. The type does not identify a time domain or timescale; modelling TAI, UTC, PHCs, monotonic time, and protocol relationships is outside this API.

Precision clock

precision_clock dispatches four mandatory clock operations:

  • read the current time;

  • set an absolute time;

  • apply a phase adjustment; and

  • set a rate offset from the nominal frequency as parts per million with a 16-bit binary fractional field.

All operations must be implemented by a clock adapter. Adjustment ranges and other hardware constraints remain the responsibility of the underlying clock implementation.

precision_clock_ptp_adapter exposes an existing Zephyr PTP clock device through this interface. It performs the required conversion between net_ptp_time and precision_time_t; it does not add capability discovery or synchronization state.

PI controller

precision_pi is an instance-based proportional-integral controller. Each instance stores its own gains, limits and integral term. precision_pi_update_interval() takes an error sample and the interval since the previous sample; the update is equivalent to:

integral = clamp(integral + (ki / interval) * error, integral_limit);
output = clamp((kp / interval) * error + integral, output_limit);

The gains are given for an interval of 1. When the plant integrates the output over the interval, as a clock does with a rate correction, the loop gain per sample is then the same for any interval. precision_pi_update() is the same update with an interval of 1.

precision_pi_set_limits() sets the two limits; a limit of 0 disables it, which is the state after precision_pi_init(). While the output is at its limit, the integral term keeps its value instead of moving further towards the limit, so it does not wind up.

The controller does not decide whether an error should be stepped, rejected, or used for rate adjustment. It also does not track synchronization, acquisition, lock, holdover, source timeout, or clock faults. Callers own those decisions and reset the accumulated integral term when their policy requires it.

The PTP and gPTP integrations initialize their controllers from CONFIG_PRECISION_TIMING_PI_KP and CONFIG_PRECISION_TIMING_PI_KI, with the limits from CONFIG_PRECISION_TIMING_PI_INTEGRAL_LIMIT_PPM and CONFIG_PRECISION_TIMING_PI_OUTPUT_LIMIT_PPM. The integer gain values express the gains in thousandths. Direct users of precision_pi_init() may provide different gains for each controller instance.

The PTP servo scales its gains by the time since its previous update when CONFIG_PTP_SERVO_SCALE_GAINS_BY_SYNC_INTERVAL is enabled. CONFIG_PTP_SERVO_STEP_THRESHOLD_MS and CONFIG_PTP_SERVO_OUTLIER_THRESHOLD_MS set the offsets above which the PTP servo steps the clock and, while locked, rejects a sample. Before the servo locks, it also steps offsets above a fixed 100 ms.

Protocol integration

PTP and the gPTP default clock-update path each keep their existing policy and use a precision_pi for the shared calculation. They initialize a PTP-clock adapter once and use precision_clock operations to access the PHC.

Sample

The Precision timing sample demonstrates checked time arithmetic, a software-backed precision clock, and PI-driven rate adjustment.

API reference

Precision Timing
Precision Time
Precision Clock
Precision Clock PTP Adapter
Precision PI Controller