一、PTP的介绍
在实际的开发中,有时候儿需要两个设备的时钟同步,而且要求的精度相对较高。那么解决这种同步的方式有很多种,比较常见的就包括本文提到的IEEE1588标准协议。这个协议早期是在工业上应用的,后来才引入到了以太网中。在实际的开发场景中,多是在嵌入式中使用,毕竟一般也是硬件对时钟有很强的同步需求。而在更上层的软件上,一般底层做好时钟同步,而其本身只需要用就可以了。不过为了同步的快捷和方便,嵌入式中对同步往往不会是在以太网的全协议栈上进行即更多可能是在链路层等中直接进行时钟的同步(可能由硬件实现)。
而在实现IEEE1588标准中,PTP协议(精确时间协议)就是一个供上层应用的时钟同步协议库,也可以叫做LinuxPTP.
二、PTP安装
首先需要检测一下本机对PTP协议的支持情况:
@a:ethtool -T enp0s31f6 #enp0s31f6为当前电脑的网上名字
Time stamping parameters for enp0s31f6:
Capabilities:
hardware-transmit
software-transmit
hardware-receive
software-receive
software-system-clock
hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off
on
Hardware Receive Filter Modes:
none
all
ptpv1-l4-sync
ptpv1-l4-delay-req
ptpv2-l4-sync
ptpv2-l4-delay-req
ptpv2-l2-sync
ptpv2-l2-delay-req
ptpv2-event
ptpv2-sync
ptpv2-delay-req
上面显示本机支持硬件时间戳。如果没有安装ethtool,可以直接使用apt命令安装即可。如果是下面的显示则表示只支持软件时间戳:
Time stamping parameters for enp6s0:
Capabilities:
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
PTP Hardware Clock: none
Hardware Transmit Timestamp Modes: none
Hardware Receive Filter Modes: none
软件和硬件时间戳的支持需要下面的枚举:
#软件时间戳需要包括参数
SOF_TIMESTAMPING_SOFTWARE
SOF_TIMESTAMPING_TX_SOFTWARE
SOF_TIMESTAMPING_RX_SOFTWARE
#硬件时间戳需要包括参数
SOF_TIMESTAMPING_RAW_HARDWARE
SOF_TIMESTAMPING_TX_HARDWARE
SOF_TIMESTAMPING_RX_HARDWARE
下面安装PTP:
安装Linuxptp:
1、直接安装
sudo apt install linuxptp -y
2、源码安装
sudo git clone git://git .code.sf.net/p/linuxptp/code linuxptp
cd linuxptp
sudo make
sudo make install
三、分析说明
LinuxPTP的默认配置文件在/etc/linuxptp/ptp4l.conf,类似如下:
cat ptp4l.conf
[global]
#
# Default Data Set
#
twoStepFlag 1
slaveOnly 0
socket_priority 0
priority1 128
priority2 128
domainNumber 0
#utc_offset 37
clockClass 248
clockAccuracy 0xFE
offsetScaledLogVariance 0xFFFF
free_running 0
freq_est_interval 1
dscp_event 0
dscp_general 0
dataset_comparison ieee1588
G.8275.defaultDS.localPriority 128
maxStepsRemoved 255
#
# Port Data Set
#
logAnnounceInterval 1
logSyncInterval 0
operLogSyncInterval 0
logMinDelayReqInterval 0
logMinPdelayReqInterval 0
operLogPdelayReqInterval 0
announceReceiptTimeout 3
syncReceiptTimeout 0
delayAsymmetry 0
fault_reset_interval 4
neighborPropDelayThresh 20000000
masterOnly 0
G.8275.portDS.localPriority 128
asCapable auto
BMCA ptp
inhibit_announce 0
inhibit_delay_req 0
ignore_source_id 0
#
# Run time options
#
assume_two_step 0
logging_level 6
path_trace_enabled 0
follow_up_info 0
hybrid_e2e 0
inhibit_multicast_service 0
net_sync_monitor 0
tc_spanning_tree 0
tx_timestamp_timeout 1
unicast_listen 0
unicast_master_table 0
unicast_req_duration 3600
use_syslog 1
verbose 0
summary_interval 0
kernel_leap 1
check_fup_sync 0
#
# Servo Options
#
pi_proportional_const 0.0
pi_integral_const 0.0
pi_proportional_scale 0.0
pi_proportional_exponent -0.3
pi_proportional_norm_max 0.7
pi_integral_scale 0.0
pi_integral_exponent 0.4
pi_integral_norm_max 0.3
step_threshold 0.0
first_step_threshold 0.00002
max_frequency 900000000
clock_servo pi
sanity_freq_limit 200000000
ntpshm_segment 0
msg_interval_request 0
servo_num_offset_values 10
servo_offset_threshold 0
write_phase_mode 0
#
# Transport options
#
transportSpecific 0x0
ptp_dst_mac 01:1B:19:00:00:00
p2p_dst_mac 01:80:C2:00:00:0E
udp_ttl 1
udp6_scope 0x0E
uds_address /var/run/ptp4l
#
# Default interface options
#
clock_type OC
network_transport UDPv4
delay_mechanism E2E
time_stamping hardware
tsproc_mode filter
delay_filter moving_median
delay_filter_length 10
egressLatency 0
ingressLatency 0
boundary_clock_jbod 0
#
# Clock description
#
productDescription ;;
revisionData ;;
manufacturerIdentity 00:00:00
userDescription ;
timeSource 0xA0
在LinuxPTP中有两种同步的方式即E2E(端到端)和P2P(点到点,即对等模式P2P通信一样 ),这里没有修改,默认使用的E2E模式。整个配置文件可以根据自己的实际场景需求进行修改,并在启动同步时指定自己的配置文件即可。配置的细节,请自行查阅相关资料。
PTP的同步精度可以达到亚微秒级,在其前还有个NTP,其时间精度在毫秒范围内。
四、同步应用示例
LinuxPTP的具体使用需要两台设备,其中一台为Master,另外一台为Slaver:
1、首先启动Master端
sudo ptp4l -i enp0s31f6 -m -H
[sudo] fpc 的密码:
ptp4l[579156.008]: selected /dev/ptp0 as PTP clock
ptp4l[579156.008]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[579156.008]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[579163.016]: port 1: LISTENING to MASTER on ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES
ptp4l[579163.016]: selected local clock cc96e5.fffe.25c701 as best master
ptp4l[579163.016]: port 1: assuming the grand master role
或执行:
sudo phc2sys -m -s CLOCK_REALTIME -c enp0s31f6 -w
phc2sys[579660.887]: enp0s31f6 sys offset 347751668382077 s0 freq +0 delay 0
phc2sys[579661.888]: enp0s31f6 sys offset 347752268687195 s1 freq +23999999 delay 0
phc2sys[579662.888]: enp0s31f6 sys offset 561871626 s2 freq +23999999 delay 0
phc2sys[579663.888]: clockcheck: clock jumped forward or running faster than expected!
phc2sys[579663.889]: enp0s31f6 sys offset 1123632524 s0 freq +23999999 delay 0
phc2sys[579664.889]: clockcheck: clock jumped forward or running faster than expected!
phc2sys[579664.889]: enp0s31f6 sys offset 1685430877 s0 freq +23999999 delay 0
phc2sys[579665.889]: clockcheck: clock jumped forward or running faster than expected!
phc2sys[579665.889]: enp0s31f6 sys offset 2247271732 s0 freq +23999999 delay 0
phc2sys[579666.889]: clockcheck: clock jumped forward or running faster than expected!
phc2sys[579666.889]: enp0s31f6 sys offset 2809072683 s0 freq +23999999 delay 0
2、再启动Slaver端
sudo ptp4l -i eno4 -m -H -s
ptp4l[13047.581]: selected /dev/ptp0 as PTP clock
ptp4l[13047.582]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[13047.582]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[13049.258]: port 1: new foreign master cc96e5.fffe.25c701-1
ptp4l[13053.261]: selected best master clock cc96e5.fffe.25c701
ptp4l[13053.261]: port 1: LISTENING to UNCALIBRATED on RS_SLAVE
ptp4l[13056.264]: master offset -397565659589904 s0 freq +0 path delay 153762974
ptp4l[13057.264]: master offset -397566270544361 s1 freq -62499999 path delay 164660164
ptp4l[13058.265]: master offset -537622701 s2 freq -62499999 path delay 164660164
ptp4l[13058.265]: port 1: UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
ptp4l[13059.265]: master offset -1064264331 s2 freq -62499999 path delay 153762974
ptp4l[13060.266]: master offset -1615581178 s2 freq -62499999 path delay 167534568
ptp4l[13061.267]: master offset -2153117101 s2 freq -62499999 path delay 167534568
ptp4l[13062.268]: master offset -2683931117 s2 freq -62499999 path delay 160648771
ptp4l[13063.268]: master offset -3221451320 s2 freq -62499999 path delay 160648771
ptp4l[13064.269]: master offset -3759124238 s2 freq -62499999 path delay 160648771
或执行:
sudo phc2sys -a -r -m
phc2sys[13811.716]: reconfiguring after port state change
phc2sys[13811.716]: selecting CLOCK_REALTIME for synchronization
phc2sys[13811.716]: selecting eno4 as the master clock
phc2sys[13811.717]: CLOCK_REALTIME phc offset -347492084400969 s0 freq +57876 delay 0
phc2sys[13812.717]: CLOCK_REALTIME phc offset -347492021760035 s1 freq +62666390 delay 0
phc2sys[13813.717]: CLOCK_REALTIME phc offset -347491970077911 s2 freq -100000000 delay 0
phc2sys[13814.718]: CLOCK_REALTIME phc offset -347491822224077 s2 freq -100000000 delay 0
phc2sys[13815.723]: CLOCK_REALTIME phc offset -347491673820002 s2 freq -100000000 delay 0
phc2sys[13816.725]: CLOCK_REALTIME phc offset -347491525675153 s2 freq -100000000 delay 0
phc2sys[13817.727]: CLOCK_REALTIME phc offset -347491377730931 s2 freq -100000000 delay 0
phc2sys[13818.733]: CLOCK_REALTIME phc offset -347491229056996 s2 freq -100000000 delay 0
phc2sys[13819.734]: CLOCK_REALTIME phc offset -347491081144728 s2 freq -100000000 delay 0
phc2sys[13820.737]: CLOCK_REALTIME phc offset -347490933012623 s2 freq -100000000 delay 0
phc2sys[13821.744]: CLOCK_REALTIME phc offset -347490784253473 s2 freq -100000000 delay 0
phc2sys[13822.749]: CLOCK_REALTIME phc offset -347490635805012 s2 freq -100000000 delay 0
phc2sys[13823.750]: CLOCK_REALTIME phc offset -347490487892731 s2 freq -100000000 delay 0
phc2sys[13824.753]: CLOCK_REALTIME phc offset -347490339767415 s2 freq -100000000 delay 0
3、说明
上面的命令执行后,会不断的进行同步,直到主从机器时间差为0,表示同步成功。上面的命令执行有些问题,没有测试准确,但方式是正确的。
五、总结
在实际工作中会遇到很多的应用场景,需要不同的软件框架和库的支持。这个不需要过多的提前准备,只要遇到后仔细看说明书应用即可,重点是要对相关的适应场景分析清楚,不能够眉毛胡子一把抓,结果交叉应用了不同的软件配置,结果肯定会有问题。