1 PPS(pulse per second)
1.1 简介
LinuxPPS provides a programming interface (API) to define in the system several PPS sources.
PPS means "pulse per second" and a PPS source is just a device which provides a high precision signal each second so that an application can use it to adjust system clock time.
A PPS source can be connected to a serial port (usually to the Data Carrier Detect pin) or to a parallel port (ACK-pin) or to a special CPU's GPIOs (this is the common case in embedded systems) but in each case when a new pulse arrives the system must apply to it a timestamp
and record it for userland.
《<kernel_src>/Documentation/pps/pps.txt》
1.2 PPS时间同步信号的输入源
1.2.1 串口信号中的DCD(Data Carrier Detect)信号
1.2.1.1 普通串口
以drivers/tty/serial/amba-pl010.c驱动为例
pl010_int();
-> pl010_modem_status();
-> uart_handle_dcd_change();
-> ld->ops->dcd_change();
-> pps_tty_dcd_change();
-> pps_event()
1.2.1.2 USB串口
以drivers/usb/serial/pl2303.c驱动为例
pl2303_read_int_callback();
-> pl2303_update_line_status();
-> usb_serial_handle_dcd_change();
-> ld->ops->dcd_change();
-> pps_tty_dcd_change();
-> pps_event()
1.2.3 GPIO
1.2.3.1 在设备树中指定使用哪个GPIO
例如
pps {
compatible = "pps-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pps>;
gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
status = "okay";
};
1.2.3.2 驱动
drivers/pps/clients/pps-gpio.c
pps_gpio_irq_handler();
-> pps_event()
1.2.4 并口
drivers/pps/clients/pps_parport.c
parport_irq();
-> pps_event();
1.2.5 PTP
1.2.5.1 判断网卡是否打开PPS功能
/sys/class/ptp/ptp0/pps_available:
This file indicates whether the PTP hardware clock supports a Pulse Per Second to the host CPU.
/sys/class/ptp/ptp0/pps_enable:
This write-only file enables or disables delivery of PPS events to the Linux PPS subsystem.
1.2.5.2 驱动
以Intel的网卡驱动为例
drivers/net/ethernet/intel/igb/igb_main.c
igb_tsync_interrupt();
-> ptp_clock_event();
-> pps_event();
1.3 文件操作接口/dev/ppsX
/*
* Char device stuff
*/
static const struct file_operations pps_cdev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.poll = pps_cdev_poll,
.fasync = pps_cdev_fasync,
.compat_ioctl = pps_cdev_compat_ioctl,
.unlocked_ioctl = pps_cdev_ioctl,
.open = pps_cdev_open,
.release = pps_cdev_release,
};
1.4 在chrony服务中使用PPS作为时间源
在配置文件/etc/chrony/chrony.conf中添加以下内容
refclock SHM 0 poll -2 refid GPS precision 1e-1 offset 0.9999 delay 0.2
refclock PPS /dev/pps0 lock NMEA refid PPS
执行"chronyc sources" 命令,出现以下结果表示配置成功
# chronyc sources | grep PPS
#- PPS 0 4 77 16 -309ms[ -309ms] +/- 29ms
2 PTP(precise time protocol; IEEE 1588协议)
2.1 简介
IEEE 1588 addresses the clock synchronization requirements of measurement and control systems. The protocol supports system-wide synchronization accuracy in the sub-microsecond range with minimal network and local clock computing resources.
《Intel ® Ethernet Controller I350 Datasheet》P457
2.2 判断网卡是否支持PTP
PTP功能需要网卡硬件支持,可通过ethtool -T xxx来查看
出现以下信息,表示网卡硬件支持PTP
# ethtool -T enp0s31f6
Time stamping parameters for enp0s31f6:
Capabilities:
hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off (HWTSTAMP_TX_OFF)
on (HWTSTAMP_TX_ON)
2.3 在chrony服务中使用PTP作为时间源
在配置文件/etc/chrony/chrony.conf中添加以下内容
refclock PHC /dev/ptp0 poll 2
执行"chronyc sources" 命令,出现以下结果表示配置成功
# chronyc sources | grep PHC
#x PHC2 0 2 377 5 +39.6s[ +39.6s] +/- 1139us
缩写:
PHC: PTP hardware clock