The IEEE 1588 standard is known as the Precision Clock Synchronization Protocol for Networked Measurement Control Systems, also known as Precision Time Protocol (PTP). The IEEE 1588 PTP enables the clocks to be distributed across an Ethernet network and accurately synchronized using a process where the distributed nodes exchange timestamped messages.
PTP system configuration
Linux PTP provides some tools to carry out time synchronization:
-
ptp4l: daemon that synchronizes the PTP Hardware Clock (PHC) from the NIC
-
phc2sys: daemon that synchronizes the PHC and the System clock
-
pmc: utility tool to configure ptp4l in run-time
Include these tools in your project with the following change to your conf/local.conf
file:
IMAGE_INSTALL:append = " linuxptp"
Note the required white space when appending a value to an array variable using the :append override syntax.
|
Rebuild the project and install the new rootfs on the target.
Kernel configuration
You can enable PTP support through the following kernel configuration.
-
PTP 1588 Clock
(CONFIG_PTP_1588_CLOCK)
-
Support for driver to use 1588 PTP framework
(CONFIG_PTP_1588_CLOCK_OPTIONAL)
-
PPS (pulse per second) high-precision time reference
(CONFIG_PPS)
These options are enabled as built-in on the default ConnectCore 91 kernel configuration file.
Device tree configuration to generate PPS signal
You can configure your Ethernet controller to generate a pulse-per-second (PPS) signal for synchronizing other peripherals.
Check the ConnectCore 91 Hardware Reference Manual for the pads that multiplex the Ethernet PPS signal.
The following example enables the PPS signal of eth0 interface using pad GPIO3_IO1
.
On the ConnectCore 93 Development Kit, this pad is already used by usdhc2, so this interface must be disabled.
To enable PPS functionality, add the pad to the associated Ethernet node pinctrl.
&usdhc2 {
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
cd-gpios = <&gpio3 00 GPIO_ACTIVE_HIGH>;
bus-width = <4>;
- status = "okay";
+ status = "disabled";
post-power-on-delay-ms = <200>;
no-sdio;
no-mmc;
};
&iomuxc {
/* EQoS RGMII */
pinctrl_eqos: eqosgrp {
fsl,pins = <
{short-cpu-prefix-ucase}_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e
....
{short-cpu-prefix-ucase}_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x5fe
{short-cpu-prefix-ucase}_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e
+ {short-cpu-prefix-ucase}_PAD_SD2_CLK__ENET_QOS_1588_EVENT0_OUT 0x57e
>;
};
/* EQoS sleep */
pinctrl_eqos_sleep: eqosgrp-sleep {
fsl,pins = <
{short-cpu-prefix-ucase}_PAD_ENET1_RD0__GPIO4_IO10 0xc00
....
{short-cpu-prefix-ucase}_PAD_ENET1_MDIO__GPIO4_IO01 0xc00
+ {short-cpu-prefix-ucase}_PAD_SD2_CLK__GPIO3_IO01 0xc00
>;
};
};
The PPS pin is accessible on the R93
resistor of the micro SDcard interface of the ConnectCore 93 Development Kit.
Rebuild the device tree and deploy it to the target.
PTP testing
Once the target has been updated with the changes and booted successfully, test the local signal.
Use the following commands on the target to verify the PTP:
-
Test the time synchronization between devices on a local network:
# ptp4l -i eth0 -p /dev/ptp0 -m -2 &
The command must be executed on each device on the network. For more configuration options, type the application name with no parameter.
-
Enable the PPS at a duty cycle of around 50%:
# echo "0 $(($(date +%s) + 1)) 0 1 1" > /sys/class/ptp/ptp0/period
This sets the PPS start time one second ahead of the current system time. The syntax of the period configuration is as follows:
# echo <idx> <ts> <tns> <ps> <pns> > /sys/class/ptp/ptpX/period
Where:
-
idx
is the channel index -
ts
is the start time in seconds (adds up withtsn
) -
tsn
is the start time in nanoseconds (adds up withts
) -
ps
is the period time in seconds (adds up withpsn
) -
pns
is the period time in nanoseconds (adds up withps
) -
To disable the PPS signal, set all values to zero:
# echo "0 0 0 0 0" > /sys/class/ptp/ptp0/period