Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jan 2023 15:19:02 +0100
From:      Sebastian Huber <sebastian.huber@embedded-brains.de>
To:        FreeBSD Hackers <freebsd-hackers@freebsd.org>
Subject:   hardpps() jitter detection
Message-ID:  <1ced1234-2e80-9137-2ae7-f98174de819d@embedded-brains.de>

next in thread | raw e-mail | index | archive | help
Hello,

I have a question related to the hardpps() jitter detection. We have=20
currently this code:

void
hardpps(struct timespec *tsp, long nsec)
{
	long u_sec, u_nsec, v_nsec; /* temps */
	l_fp ftemp;

	NTP_LOCK();

	/*
	 * The signal is first processed by a range gate and frequency
	 * discriminator. The range gate rejects noise spikes outside
	 * the range +-500 us. The frequency discriminator rejects input
	 * signals with apparent frequency outside the range 1 +-500
	 * PPM. If two hits occur in the same second, we ignore the
	 * later hit; if not and a hit occurs outside the range gate,
	 * keep the later hit for later comparison, but do not process
	 * it.
	 */
	time_status |=3D STA_PPSSIGNAL | STA_PPSJITTER;
	time_status &=3D ~(STA_PPSWANDER | STA_PPSERROR);
	pps_valid =3D PPS_VALID;
	u_sec =3D tsp->tv_sec;
	u_nsec =3D tsp->tv_nsec;
	if (u_nsec >=3D (NANOSECOND >> 1)) {
		u_nsec -=3D NANOSECOND;
		u_sec++;
	}
	v_nsec =3D u_nsec - pps_tf[0].tv_nsec;
	if (u_sec =3D=3D pps_tf[0].tv_sec && v_nsec < NANOSECOND - MAXFREQ)
		goto out;
	pps_tf[2] =3D pps_tf[1];
	pps_tf[1] =3D pps_tf[0];
	pps_tf[0].tv_sec =3D u_sec;
	pps_tf[0].tv_nsec =3D u_nsec;

	/*
	 * Compute the difference between the current and previous
	 * counter values. If the difference exceeds 0.5 s, assume it
	 * has wrapped around, so correct 1.0 s. If the result exceeds
	 * the tick interval, the sample point has crossed a tick
	 * boundary during the last second, so correct the tick. Very
	 * intricate.
	 */
	u_nsec =3D nsec;
	if (u_nsec > (NANOSECOND >> 1))
		u_nsec -=3D NANOSECOND;
	else if (u_nsec < -(NANOSECOND >> 1))
		u_nsec +=3D NANOSECOND;
	pps_fcount +=3D u_nsec;
	if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ)
		goto out;
	time_status &=3D ~STA_PPSJITTER;

The v_nsec value is used to reject a sample if the time difference is=20
out of range. The v_nsec value is computed using the current time at the=20
PPS event (tsp) and the time at the previous PPS event (pps_tf[0]).=20
These time points are measured by a clock which is adjusted by the=20
hardpps() outputs. Wouldn't it be better to use the uncontrolled input=20
value (nsec) for the jitter detection? This is how Linux does it:

https://github.com/torvalds/linux/blob/master/kernel/time/ntp.c#L1055

Is this maybe a typo, and the

	if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ)

should be

	if (u_nsec > MAXFREQ || u_nsec < -MAXFREQ)

?

--=20
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht M=C3=BCnchen
Registernummer: HRB 157899
Vertretungsberechtigte Gesch=C3=A4ftsf=C3=BChrer: Peter Rasmussen, Thomas=
 D=C3=B6rfler
Unsere Datenschutzerkl=C3=A4rung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1ced1234-2e80-9137-2ae7-f98174de819d>