More precisely, I'm talking about how to build the boundary clock by very limited budget.
If you want to learn more, please visit our website.
Ravenna/AES67 is heavily relying on PTPv2 (IEEE-). Although Zman-based Merging Anubis and Merging Hapi Mk II can be the PTP grandmaster clock in the Ravenna/AES67 network, but if look at the PTP clock source list, it indicates that the GPS has higher priority than internal oscillator. The Best Master Clock Algorithm, BMCA will always choose GPS-corrected one as the GMC.
But the price of GPS-corrected PTP GMCs are high. Fortunately we can build our own PTP GMC thru Linux system with reasonable expense: a retired PC with PCIe NICs and build as a PTP boundary clock. One NIC will be slave (to another GPS grandmaster clock) and all other NICs will be the master clock to the Ravenna network.
This was the Zman-based Merging Anubis as PTP GMC and the deviation showed on Hapi Mk II. It's about 7.6ppm @ DXD sample rate for me. The number actually was quite good, meets the AES67's requirement <±10ppm.
This was my home-made GPS PTP GMC. The deviation became <±1ppm. I think I can say it's an improvement.
The equipments I use:
- a current HQPlayer Embedded server running Ubuntu Server 22.04 / stock 5.15 low-latency kernel, still has two PCIe slots available for additional NICs.
- an affordable TMB GPS PTP GMC as clock source.
- a Merging customized NIC NET-MSC-GBEX1 (actually it's an Intel L. I know it's very, very expensive compared to other L but it worths. I'll talk about that later.)
- a retail, genuine Intel i350 dual-port NIC
Last three items was newly acquired and the total expense was about USD.
Before setup we have to make sure the NICs support PTP hardware time stamping using this command:
ethtool -T <interface>
Here's Asus TUF Gaming's on-board Realtek RTL 2.5GbE NIC. Does not support hardware time stamping and no hardware clock. I noticed all of my Realtek NICs didn't support hardware time stamping. If you want to acquire Realtek NIC for PTP must keep in mind that it might just support software time stamping and does not suitable for the role of PTP GMC.
Here's the Merging's NET-MSC-GBEX1. It supports HW time stamping and a HW clock (numbered 0).
Here's the retail i350 and also looks good. Two HW clocks inside (numbered 1 and 2).
In Linux system we need to install LinuxPTP package:
sudo apt install linuxptp
LinuxPTP package contains ptp4l, phc2sys and pmc. The ptp4l is used for initialization, sanitize HW clocks on NICs and decides the role (MC, BC or TC). The phc2sys is used for synchronization between system clock and NIC's HW clock. The pmc is used for function check / verification.
The configuration for my low cost TMB is quite simple. I just power it on, put the antenna out of my window for better GPS satellite signal and change to two-step methods then leave there. Originally I tried to put TMB into Ravenna/AES67 network as GMC, but the GPS was too sensitive and completely destroy the audio stream--always stuttering for re-syncing the clock:
So I decided setup a boundary clock to make it more Ravenna/AES67 welcome.
I set Merging's NET-MSC-GBEX1 (enp9s0) as slave port. It has the best PTP HW clock which can gain 0ppm if use it solely in my environment (this is why I said it worths every penny).
Once the Merging's NET-MSC-GBEX1 synced with TMB it can be the best clock source after all. I believe Merging and Intel all did excellent job for choosing the quality of the HW clock for NET-MSC-GBEX1.
To configure i350 (enp5s0f0, enp5s0f1) as master port for Ravenna/AES67. I also adjusted Kp = 0.1 / Ki = 0.001 of proportional-integral servo to make smoother response. And also set PTP packets has highest priority (DSCP 46 this case).
Edit /etc/linuxptp/ptp4l.conf:
dscp_event 46
dscp_general 46
pi_proportional_scale 0.1
pi_integral_scale 0.001
boundary_clock_jbod 1
[enp9s0]
masterOnly 0
[enp5s0f0]
masterOnly 1
[enp5s0f1]
masterOnly 1
Back to CLI and enable / start the ptp4l service.
Next is to configure phc2sys to sync system clock. BC's mechanism would read and drop the time stamps from master (here is TMB), generate system clock's time stamp to master (here is i350), i350 reads and drops the system time stamp then use HW clock's time stamp to talk to Ravenna/AES67. Complex, huh? ' So the system clock must be synced as well.
Just make a service (create /lib/systemd/system/phc2sys.service):
ExecStart=/usr/sbin/phc2sys -a -rr
This command can sync all clocks by master (here is Merging's NET-MSC-GBEX1). Enable / start the service.
After done these step, if you see the deviation is larger than Merging's internal clock, don't worry just completely shutdown your server to reset the HW clock. Start the server and check the ptp4l status again:
sudo pmc 'get PARENT_DATA_SET' 'get CURRENT_DATA_SET' 'get PORT_DATA_SET' 'get TIME_STATUS_NP' -u -b 0
Here's the status of my system. The GMC's MAC address F7-DA-B9 was from Merging's NET-MSC-GBEX1. The ***f7dab9-2 had a FAULTY code because I didn't connect the second port of i350 to any network so it's normal. Other than that everything looks quite good.
And the statistics in Hapi's Advanced page also looks good. The network delta drives by Kp = 0.1 / Ki = 0.001 PI servo. You can try other numbers but I still suggest 0.1 / 0.001 for the best result.
California Triangle are exported all over the world and different industries with quality first. Our belief is to provide our customers with more and better high value-added products. Let's create a better future together.
I've wanted to build a low-cost open source Linux system that could function as a PTP grandmaster for a while now. This should be pretty doable with IEEE readily available (if you know where to look) and low-cost GPS receivers with reasonable quality 1PPS outputs.
Hard requirements:
Nice to haves:
JCOM1
RS-232 port (ideally I want 3.3V TTL for GNSS module interfacing), but some online discussions suggest the port doesn't work (or the person doesn't know what they're doing). I'd like to try this if I could convince myself that there's a low latency and low jitter path for the 1PPS signal.One of the most compelling features of the NanoPi R5S is that it's easy to buy from many vendors (I ordered from Amazon.com) and comes with an enclosure. Once you receive it's ready to go as a router with no other messing around.
Let's walk through some of the features.
The RK is focused around 4xARM Cortex-A55 cores.
For Ethernet, the RK processor has two integrated Ethernet MACs (GMAC
) that support IEEE - (version 1) and IEEE - (version 2) and works with PTP over UDP (layer 3) and over Ethernet (layer 2). The GMAC also supports Jumbo frames (up to bytes, for tagged VLAN packets). In addition to this seems to support frames up to 16kB which I've never seen or used and definitely don't have hardware to use with it.
Initial testing shows that linuxptp
and the 5.10 Linux kernel 'just work' out of the box on FriendlyWrt and was able to synchronize with another device on my network. Driver and hardware support can be verified by reviewing the kernel boot logs:
At minimum the 'LAN' port will function using the integrated Ethernet controller.
These Realtek RTL are pretty ubiquitous for low-cost Ethernet PCIe controllers and don't seem to have the issues some of the early Intel i225 controllers have (fixed with rev 3 and newly release i226). I've been using one of these (rev 05) integrated in to my workstation motherboard for well over years without issue on Arch Linux with the mainline kernel driver.
I was surprised to learn that these Etherent controllers also support IEEE -, IEEE -, and IEEE 802.1AS. Howver, the mainline kernel driver doesn't support it. It does appear that that the Realtek vendor out-of-tree driver (version 9.009.02 at time of writing) does seem to support PTP. I haven't verified this just yet.
There's a 12-pin FPC connector that exposes 3x integrated UARTs, GPIOS, and PWM capture pins. With minimal device tree updates this easily supports UART5 via /dev/ttyS5
and GPIO3_C5
/ gpio-117
works with the 1PPS input in IRQ mode.
The enclosure feels high quality and serves well as a heatsink. It's readily accessible and often easier to buy the NanoPi R5S with the case then without.
Furthermore, there's unused cut-out for a SMA WiFi antenna adapter on the back. I hope to use this for a GNSS antenna once I figure out how to tuck the GNSS module into the case.
Ships with FriendlyWrt 21.02. Out of the box linuxptp
works largely out of the box.
I built FriendlyWrt 22.03 so I could incorporate the UART5
and 1PPS input device tree changes without much hassle using the directions and an MicroSDXC card.
After some initial wiring with a 12-pin FPC breakout out board, I was able to get gpsd
to read a UBLOX NEO-M8N gps module. I then fed that to chrony
which verified the time was pretty close to right. Finally, I configured chrony
to read the 1PPS signal (/dev/pps1
in my case) to precisely tune the clock after setting the time.
Hardware timestamping info:
Chrony timing stats comparing time to public NTP servers:
Some PPS testing testing using ppswatch
I need to use a proper GNSS antenna that can be well placed outside. Currently I'm using a quadcopter GNSS module with integrated ceramic antenna and placed it in the window. With a different GNSS module with a SMA connector I'll be able to place the antenna outside for better signal. Currently the signal drops out as the GNSS satellites come and go. I've ordered a cheap (possibly fake) UBLOX NEO-M8N from somewhere in China with a SMA and U.FL connector. In a perfect world I'll be able to tuck this + the FPC wiring in the enclosure and run a U.FL to SMA cable to the plugged WiFi SMA cutout in the enclosure.
Need to dig in to the out-of-tree kernel driver and see why it doesn't show up as PTP hardware clock.
The linuxptp
daemon in OpenWrt works well enough on a single port, but I'd make to make it work on all ports. The struggle here is that typically I'd bridge the interfaces and be done, but PTP doesn't really work with bridges. Need to think about what's a sensible network setup where I can keep this as a 'simple' timing device and not turn in to a complicated router.
Recording the chrony statistics in something like InfluxDB would be idea, but not sure if that'd work well on an embedded device. Then display a dashboard in Grafana to track performance metrics:
It's unclear to me why there's so much delay and jitter in the PPS timestamping. Likely this is just the latency of the kernel servicing the IRQ up to the resolution of the main system clock (which I need to look-up, 24 MHz?).
First steps are to turn off dynamic ticks and use the performance cpufreq
governor.
Beyond that, then using the PWM capture unit (PWM15
) would be much better. Seems that the fastest I can drive the PWM peripheral is 24 MHz which means only about 41.67ns of resolution, but this seems better then the ±ns observed with the PPS test above with no notuning.
I verified the PWM15
output works, but the capture and compare unit reports 'not implemented' during cursory exploration.
Assemble a FriendlyWrt image that just works out of the box for this application that incorporates all the changes above.
Create a simple PCB to integrate a UBLOX NEO-M8N (or better) that easily interface with the FPC expansion connector. Ideally this would be easily tucked within the enclosure and expose a SMA connector at the WiFi antenna cut-out near the USB-C connector.