PTP
Overview
The PTP sample application for Zephyr will enable PTP (IEEE 1588-2019) support.
The source code for this sample application can be found at: samples/net/ptp.
Requirements
For generic host connectivity, that can be used for debugging purposes, see Networking with native_sim board for details.
For testing with embedded devices, an Ethernet PHY with support for timestamping must be used. The sample application has been tested with the Ethernet PHYs on a Nucleo H563ZI with ptp4l daemons, a GPS Clock (direct link), a PTP-capable switch and with a GPS Clock + PTP-capable switch.
Building and Running
A good way to run this sample is to run this PTP application inside Native simulator - native_sim board as described in Networking with native_sim board or with embedded device like Nucleo H563ZI, Nucleo H743ZI, Nucleo H745ZI-Q or Nucleo F767ZI.
Note that PTP is only supported for boards that have an Ethernet port and which has support for collecting timestamps for sent and received Ethernet frames.
Follow these steps to build the PTP sample application:
west build -b <board to use> samples/net/ptp
Interpreting net ptp Output
The shell provides two complementary views:
net ptp: instance-level summary (clock identity, current/parent dataset, best foreign time transmitter, and a per-port state table).net ptp <port>(for examplenet ptp 1): detailed view for one port, including configuration and runtime counters/timers.
Example of net ptp output as a grandmaster:
uart:~$ net ptp
PTP Instance:
Clock ID : 02:00:00:FF:FE:00:00:01
Clock Type : ORDINARY
Domain : 0
Priorities : 128 / 128
Time source : INTERNAL_OSCILLATOR (0xa0)
Ports : 1
TR only : no
PHC now : 95.703698720
Current dataset:
steps_rm : 0
offset_from_tt: 0 ns
mean_delay : 0 ns
sync status : stable
Parent/GM dataset:
grandmaster : 02:00:00:FF:FE:00:00:01 (p1=128 p2=128 class=248 acc=0xfe)
parent port : 02:00:00:FF:FE:00:00:01-0
UTC offset : 37
Best foreign transmitter : none
Port Interface State
1 1 GRAND_MASTER
Example of net ptp 1 output as a grandmaster:
uart:~$ net ptp 1
PTP Port 1:
interface : 1
port identity : 02:00:00:FF:FE:00:00:01-1
Configuration:
state : GRAND_MASTER
enabled : yes
time transmitter only: no
announce log itv : 1
announce timeout : 5
sync log itv : 0
min delay_req log itv: 0
delay mechanism : E2E
delay asymmetry : 0 ns
mean link delay : 0 ns
Runtime:
seq announce/delay/signaling/sync: 66 / 0 / 0 / 132
timeouts bits : announce=0 delay=0 sync=0 qualification=0
timer remaining ms : announce=1677 delay=0 sync=677 qualification=0
PHC now : 145.138244620
best foreign : none
Example of net ptp output as a time receiver:
uart:~$ net ptp
PTP Instance:
Clock ID : 02:00:00:FF:FE:00:00:01
Clock Type : ORDINARY
Domain : 0
Priorities : 128 / 128
Time source : INTERNAL_OSCILLATOR (0xa0)
Ports : 1
TR only : no
PHC now : 1774472701.341945363
Current dataset:
steps_rm : 2
offset_from_tt: 22 ns
mean_delay : 639 ns
sync status : stable
Parent/GM dataset:
grandmaster : 02:00:00:FF:FE:00:00:10 (p1=128 p2=128 class=6 acc=0x21)
parent port : 02:00:00:FF:FE:00:00:20-2
UTC offset : 37
Best foreign transmitter : 02:00:00:FF:FE:00:00:20-2 (records=2)
Dataset : p1=128 p2=128 steps_rm=1 receiver=02:00:00:FF:FE:00:00:01-1
Port Interface State
1 1 TIME_RECEIVER
Example of net ptp 1 output as a time receiver:
uart:~$ net ptp 1
PTP Port 1:
interface : 1
port identity : 02:00:00:FF:FE:00:00:01-1
Configuration:
state : TIME_RECEIVER
enabled : yes
time transmitter only: no
announce log itv : 1
announce timeout : 5
sync log itv : 0
min delay_req log itv: 0
delay mechanism : E2E
delay asymmetry : 0 ns
mean link delay : 0 ns
Runtime:
seq announce/delay/signaling/sync: 0 / 1268 / 0 / 0
timeouts bits : announce=0 delay=0 sync=0 qualification=0
timer remaining ms : announce=9459 delay=539 sync=4408 qualification=0
PHC now : 1774472701.764088663
best foreign : 02:00:00:FF:FE:00:00:20-2 (p1=128 p2=128 steps_rm=1)
Useful fields in these views:
TR only: whetherCONFIG_PTP_TIME_RECEIVER_ONLYis enabled.PHC now: current hardware PTP clock time read from the Ethernet PHC.steps_rm: number of network steps to the selected grandmaster.offset_from_ttandmean_delay: current synchronization offset and path delay estimate.Best foreign transmitter: best Announce candidate seen on the network for BMCA/state decision.
Role/state interpretation:
GRAND_MASTERwithbest foreign : nonemeans no eligible foreign transmitter has been selected yet, so the local clock is currently acting as grandmaster.Once valid Announce messages are received and selected, the state typically transitions to
TIME_RECEIVERorPASSIVEdepending on BMCA results.
Setting up Linux Host
By default PTP in Zephyr will not print any PTP debug messages to console.
One can enable debug prints by setting
CONFIG_PTP_LOG_LEVEL_DBG in the config file.
First, get linuxptp project sources and build it:
git clone http://git.code.sf.net/p/linuxptp/code linuxptp
cd linuxptp
make
Use Linux Host with an Embedded Device
Create a configuration file for ptp4l, for example
p2p.cfg, with contents like this:
[global]
# Delay mechanism must match your configuration
delay_mechanism E2E
# Use hardware timestamping if your NIC supports it
time_stamping hardware
# Choose the transport that matches your network:
# - L2 = EtherType 0x88f7 (typical in TSN/industrial, needs L2 reachability)
# - UDPv4 = common in IT networks / routed segments
network_transport UDPv4
# Must match switch domain
domainNumber 0
# Message rates (adjust as needed)
logSyncInterval -3
logMinDelayReqInterval -3
# Quality-of-life
tx_timestamp_timeout 20
summary_interval 1
and start it like this:
sudo ./ptp4l -i zeth -f /path/to/config/p2p.cfg -m
Use Linux host with native_sim
This workflow uses three or four terminals:
Terminal #1: host network setup (
tools/net-tools)Terminal #2:
ptp4lTerminal #3: Zephyr
native_simprocessTerminal #4 (optional): attach to Zephyr shell UART PTY
Step 1 - Build Zephyr application
west build -b native_sim/native/64 samples/net/ptp
Step 2 - Create host TAP interface
In tools/net-tools:
sudo ./net-setup.sh start
Keep this interface while the sample is running. When done, remove it with:
sudo ./net-setup.sh stop
Step 3 - Start ptp4l
sudo ./ptp4l -4 -i zeth -m -q -l 6 -S
If ptp4l starts before Zephyr, temporary messages like link down and
FAULTY are expected. After Zephyr creates and brings up zeth, ptp4l
transitions back to LISTENING and continues normal BMCA operation.
Step 4 - Start Zephyr native_sim image
build/zephyr/zephyr.exe
Expected startup output includes:
uart connected to pseudotty: /dev/pts/<N>
*** Booting Zephyr OS build ... ***
<inf> net_ptp_sample: Runs forever
Runs forever is expected because CONFIG_NET_SAMPLE_RUN_DURATION=0 in
the sample configuration.
Step 5 - Attach to Zephyr shell
If screen is installed:
screen /dev/pts/<N>
If screen is not installed, socat can be used:
socat -,rawer,echo=0,escape=0x1d /dev/pts/<N>,rawer,echo=0
Press Ctrl-] to leave socat.
Step 6 - Check PTP state in Zephyr shell
uart:~$ net ptp
uart:~$ net ptp 1
On native_sim, seeing both host and Zephyr transmit Announce/Sync traffic
is normal. Depending on BMCA data, Zephyr can remain GRAND_MASTER even when
best foreign is present.