PTP Architecture Guide
This guide provides an overview of time synchronization in automotive systems, and gives pointers on how to set up and configure PTP (Precision Time Protocol).
It is assumed that all machines already have ROS 2 installed.
This repository provides Ansible roles
for PTP configuration in the ansible/
directory for easy installation.
Overall Goal
All devices in the vehicle, including all of their clocks if they have multiple, must be synchronized in order for the system to function correctly.
Otherwise, timestamps from different sensors might be far apart, and sensor fusion would be impossible or inaccurate, log entries from different ECUs would be out of order, and so on.
The overall synchronization architecture is usually tree-shaped:
- One time source (NTP, GNSS, a dedicated grandmaster clock device) provides current UTC
- One ECU's system clock is synced to the time source
- All other clocks are directly or indirectly synced to that ECU's system clock
- Sensors and other hardware devices are synced via sensor-specific methods
Time Source
To synchronize the vehicle with the outside world, a time source is required.
Below are the most common options, in order of preference.
GNSS
The vehicle usually has a GNSS receiver already, and that receiver already reports accurate
time obtained from satellites. To make use of this time, NTP clients like chrony can be set
up to sync to the time output by GNSS interface software like gpsd.
See this guide by Kovasky Buezo for setup details.
PTP Grandmaster Clock
This solution relies on a PTP Grandmaster Clock such as these and these. The advantage is that no special software setup is needed, the clocks act as normal PTP instances on the network. ECUs can then sync to the grandmaster clock as their PTP master.
NTP using chrony
This is a simple, and usually accurate-enough solution that requires an internet connection.
The chrony software can query multiple NTP (network time protocol) servers, and behaves well
even in unstable networks.
See the guide by RedHat for setup details.
NTP using systemd-timesyncd
A simpler alternative to chrony is systemd-timesyncd, which is an SNTP (simple network time
protocol) client. It queries only one server and might have less accuracy in unstable networks.
Use this only if none of the other options are viable.
Sensor Synchronization
The time synchronization mechanisms supported vary by sensor type and make, but mostly follow the below pattern:
Ethernet and Base-T1 Sensors
Most LiDARs and imaging radars fall into this category.
These usually support at least one PTP profile. See the PTP guide below.
GMSL Sensors
Most cameras fall into this category.
These have sensor-specific timing characteristics and usually use trigger signals generated by an ECU. Refer to the sensor's specific instructions.
CAN and CAN-FD Sensors
Most radars, IMUs etc. fall into this category.
While a standard for time synchronization over CAN(-FD) exists (AutoSAR TimeSync over CAN), this is not supported by many sensors, and not supported in Linux. For most CAN(-FD) based sensors, there is no viable option to synchronize time. Confirm via measurements whether there is a significant or variable time offset.
PTP Architecture
While an exhaustive guidebook on PTP is hard to provide, due to the complexity of the topic, this guide provides common pointers and pitfalls to avoid when setting up PTP.
PTP Software
There are two common software stacks for PTP on Linux: linuxptp and ptpd. linuxptp
provides a more feature-rich implementation with its ptp4l and phc2sys programs and is the
recommended choice for most use cases.
Warning
SYNC.TOOLING only supports linuxptp. ptpd is unsupported.
Tip
Use linuxptp unless there is a strong reason not to.
ptp4l participates in PTP synchronization over the network on one or more interfaces.
It is configured with one local clock and will synchronize it to the best available PTP clock
on the network (slave mode) or let other devices synchronize to it (master mode).
phc2sys is used to synchronize multiple clocks on the same ECU, e.g. the system clock and
a network interface's hardware clock.
Install and configure PTP4L and PHC2SYS via the Ansible roles provided in this repository:
For manual setups, see the excellent RedHat guide.
Named Unix Domain Sockets
All ptp4l instances configured via the Ansible roles use named Unix domain sockets at
/var/run/ptp4l@<instance_name>. This is mandatory for SYNC.TOOLING and phc2systo
communicate with ptp4l instances and for multiple instances to coexist on the same machine.
Time Stamping Modes
ptp4l can be configured with either the -H flag for hardware time stamping, or -S for
software time stamping.
Hardware time stamping utilizes the network interface's hardware clock to timestamp packets
exactly when they are sent or received. This is the most accurate method, but requires hardware
support. Additionally, it has to be ensured that the hardware clock and system clock are
synchronized. This is done with phc2sys.
Software time stamping uses the system clock to timestamp packets when they enter or leave the kernel network stack. This is less accurate, but compatible with almost all hardware.
To find out what time stamping modes are supported by a network interface (e.g. eno1), run
Example output:
| Only Software Time Stamping Supported | Hardware Time Stamping Supported |
|---|---|
Warning
Some USB Ethernet adapters do not even support software time stamping and cannot be used for PTP synchronization.
PTP Profiles
There are three main PTP profiles:
| Profile | Description |
|---|---|
| PTPv2 (1588v2) | The least precise, but most forgiving profile. |
| gPTP (802.1AS) | More precise, but highly restrictive requirements. |
| Automotive | A gPTP profile tuned for automotive use cases. |
Which one to use depends on hardware support and network architecture.
Bug
Do not mix PTP profiles in the same network segment, as this can lead to synchronization faults.
Bug
Never launch multiple ptp4l or ptpd instances on the same network interface, as this
can lead to synchronization faults.
PTPv2
This is the most easily deployed profile. It can be used on bus-like network links with many participants, and can use UDP/IP transport.
PTPv2
- can run over UDPv4 (
-4), UDPv6 (-6), or raw Ethernet/L2 (-2). - supports time stamping in software (
-S) or hardware (-H). - can operate in either end-to-end (
-E) or peer-to-peer (-P) mode.
Bug
Do not mix software and hardware time stamping between a master and slave, as implicit UTC-TAI conversions will lead to time offsets of roughly 37 seconds.
Bug
Do not mix end-to-end and peer-to-peer mode in the same network segment, as this can lead to synchronization faults.
Tip
Use hardware time stamping (-H) where possible. Use UDPv4 (-4) for easy network setup.
Use peer-to-peer mode (-P) for best performance. If there are compatibility issues,
fall back to end-to-end mode (-E).
gPTP, Automotive
These profiles are highly restrictive. Network equipment like switches has to support the profile, and all network links where the profile is used have to be 1-to-1.
gPTP and Automotive PTP
- can only run over raw Ethernet/L2 (
-2) - support time stamping in hardware (
-H) only - operate in peer-to-peer mode (
-P) only
Use these if they are required by the hardware, such as automotive sensors.
PTP4L provides configurations (-f /path/to/file.conf) for both profiles. These are typically
located in /usr/share/doc/linuxptp/configs/.
Bug
Do not run gPTP or Automotive PTP on network links with more than two participants, as this will lead to synchronization faults. If e.g. you want to sync four sensors with gPTP from one ECU, the ECU needs four separate network interfaces, each supporting gPTP.
ECU PTP Architecture
ECUs typically have multiple clocks: one system clock and multiple hardware clocks, usually
one per network card1. These have to be synchronized to each other (locally on the
ECU), so be sure to understand which clocks are available, e.g. using the ethtool -T command
detailed in the Time Stamping Modes section.
For every ECU, the system clock and all hardware clocks that are being used for PTP have to be synchronized to each other. There are multiple patterns to achieve this.
Info
By default, ptp4l participates as a server or client automatically based on the PTP peers.
In production, the role of each PTP instance should be explicitly configured, e.g. with the
--clientOnly=1 and --serverOnly=1 options (--slaveOnly=1 and --masterOnly=1 before
v4.0). Ensure that PHC2SYS source (-s) and destination (-c) clocks are configured
accordingly.
Software vs Hardware Time Stamping
The simplest architecture is to use software time stamping:
With hardware time stamping, PHC2SYS is required to synchronize the system and hardware clocks:
- role: ptp4l
vars:
ptp4l_instance_name: eno1
ptp4l_interfaces: ["eno1"]
ptp4l_mode: client
ptp4l_config_file: /usr/share/doc/linuxptp/configs/default.cfg
- role: phc2sys
vars:
phc2sys_instance_name: eno1
phc2sys_source: /dev/ptp0
phc2sys_destination: CLOCK_REALTIME
phc2sys_utc_offset: 0
phc2sys_wait_for_ptp: true
phc2sys_ptp4l_uds: /var/run/ptp4l@eno1
Number of PTP4L/PHC2SYS Instances
In general, one ptp4l instance can only operate on one clock. It can however operate on multiple
network interfaces, provided that both have the same hardware clock, or that software time
stamping is used.
A single phc2sys instance can synchronize multiple clocks to a common source clock.
enp0s0f0 and enp0s0f1 use the same hardware clock, ptp0, so only one ptp4l instance is
needed:
- role: ptp4l
vars:
ptp4l_instance_name: enp0
ptp4l_interfaces: ["enp0s0f0", "enp0s0f1"]
ptp4l_mode: server
ptp4l_config_file: /usr/share/doc/linuxptp/configs/default.cfg
- role: phc2sys
vars:
phc2sys_instance_name: enp0
phc2sys_source: CLOCK_REALTIME
phc2sys_destinations: ["/dev/ptp0"]
phc2sys_utc_offset: 0
enp0s0f0 and enp1s0f0 have different hardware clocks, ptp0 and ptp1, so two ptp4l
instances are needed.
- role: ptp4l
vars:
ptp4l_instance_name: enp0s0f0
ptp4l_interfaces: ["enp0s0f0"]
ptp4l_mode: server
ptp4l_config_file: /usr/share/doc/linuxptp/configs/default.cfg
- role: ptp4l
vars:
ptp4l_instance_name: enp1s0f0
ptp4l_interfaces: ["enp1s0f0"]
ptp4l_mode: server
ptp4l_config_file: /usr/share/doc/linuxptp/configs/default.cfg
- role: phc2sys
vars:
phc2sys_instance_name: sys_to_ptp
phc2sys_source: CLOCK_REALTIME
phc2sys_destinations: ["/dev/ptp0", "/dev/ptp1"]
phc2sys_utc_offset: 0
If it is undesirable to run only one phc2sys instance, e.g. due to different synchronization
settings for different clocks, multiple phc2sys instances can be used:
- role: ptp4l
vars:
ptp4l_instance_name: enp0s0f0
ptp4l_interfaces: ["enp0s0f0"]
ptp4l_mode: server
ptp4l_config_file: /usr/share/doc/linuxptp/configs/default.cfg
- role: ptp4l
vars:
ptp4l_instance_name: enp1s0f0
ptp4l_interfaces: ["enp1s0f0"]
ptp4l_mode: server
ptp4l_config_file: /usr/share/doc/linuxptp/configs/default.cfg
- role: phc2sys
vars:
phc2sys_instance_name: ptp0
phc2sys_source: CLOCK_REALTIME
phc2sys_destinations: ["/dev/ptp0"]
phc2sys_utc_offset: 0
- role: phc2sys
vars:
phc2sys_instance_name: ptp1
phc2sys_source: CLOCK_REALTIME
phc2sys_destinations: ["/dev/ptp1"]
phc2sys_utc_offset: 0
Each ptp4l instance automatically gets a unique Unix domain socket at
/var/run/ptp4l@<name>, ensuring SYNC.TOOLING and PHC2SYS can communicate with them.
Bug
When running multiple ptp4l instances, their local Unix Domain Sockets (UDS) must be
configured to be different, by applying the --uds_address /var/run/ptp4l@<interface>
option. Otherwise, PHC2SYS and SYNC.TOOLING will not be able to communicate with them.
-
Usually, one network interface card (NIC) has one or more hardware clocks (e.g.
/dev/ptp0), which are each assigned to one or more network interfaces (e.g.eno1). This is vendor and model specific, so check the documentation of the NIC and useethtool -Tto confirm. ↩