1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2015 Intel Corporation. 3 4PTP Client Sample Application 5============================= 6 7The PTP (Precision Time Protocol) client sample application is a simple 8example of using the DPDK IEEE1588 API to communicate with a PTP time transmitter 9to synchronize the time on the NIC and, optionally, on the Linux system. 10 11Note, PTP is a time syncing protocol and cannot be used within DPDK as a 12time-stamping mechanism. See the following for an explanation of the protocol: 13`Precision Time Protocol 14<https://en.wikipedia.org/wiki/Precision_Time_Protocol>`_. 15 16 17Limitations 18----------- 19 20The PTP sample application is intended as a simple reference implementation of 21a PTP client using the DPDK IEEE1588 API. 22In order to keep the application simple the following assumptions are made: 23 24* The first discovered time transmitter is the main for the session. 25* Only L2 PTP packets are supported. 26* Only the PTP v2 protocol is supported. 27* Only the time receiver clock is implemented. 28 29 30How the Application Works 31------------------------- 32 33.. _figure_ptpclient_highlevel: 34 35.. figure:: img/ptpclient.* 36 37 PTP Synchronization Protocol 38 39The PTP synchronization in the sample application works as follows: 40 41* Time transmitter sends *Sync* message - the time receiver saves it as T2. 42* Time transmitter sends *Follow Up* message and sends time of T1. 43* Time receiver sends *Delay Request* frame to PTP time transmitter and stores T3. 44* Time transmitter sends *Delay Response* T4 time which is time of received T3. 45 46The adjustment for time receiver can be represented as: 47 48 adj = -[(T2-T1)-(T4 - T3)]/2 49 50If the command line parameter ``-T 1`` is used the application also 51synchronizes the PTP PHC clock with the Linux kernel clock. 52 53Compiling the Application 54------------------------- 55 56To compile the sample application see :doc:`compiling`. 57 58The application is located in the ``ptpclient`` sub-directory. 59 60 61Running the Application 62----------------------- 63 64To run the example in a ``linux`` environment: 65 66.. code-block:: console 67 68 ./<build_dir>/examples/dpdk-ptpclient -l 1 -n 4 -- -p 0x1 -T 0 69 70Refer to *DPDK Getting Started Guide* for general information on running 71applications and the Environment Abstraction Layer (EAL) options. 72 73* ``-p portmask``: Hexadecimal portmask. 74* ``-T 0``: Update only the PTP time receiver clock. 75* ``-T 1``: Update the PTP time receiver clock and synchronize the Linux Kernel to the PTP clock. 76 77 78Code Explanation 79---------------- 80 81The following sections provide an explanation of the main components of the 82code. 83 84All DPDK library functions used in the sample code are prefixed with ``rte_`` 85and are explained in detail in the *DPDK API Documentation*. 86 87 88The Main Function 89~~~~~~~~~~~~~~~~~ 90 91The ``main()`` function performs the initialization and calls the execution 92threads for each lcore. 93 94The first task is to initialize the Environment Abstraction Layer (EAL). The 95``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()`` 96function. The value returned is the number of parsed arguments: 97 98.. literalinclude:: ../../../examples/ptpclient/ptpclient.c 99 :language: c 100 :start-after: Initialize the Environment Abstraction Layer (EAL). 8< 101 :end-before: >8 End of initialization of EAL. 102 :dedent: 1 103 104And than we parse application specific arguments 105 106.. literalinclude:: ../../../examples/ptpclient/ptpclient.c 107 :language: c 108 :start-after: Parse specific arguments. 8< 109 :end-before: >8 End of parsing specific arguments. 110 :dedent: 1 111 112The ``main()`` also allocates a mempool to hold the mbufs (Message Buffers) 113used by the application: 114 115.. literalinclude:: ../../../examples/ptpclient/ptpclient.c 116 :language: c 117 :start-after: Creates a new mempool in memory to hold the mbufs. 8< 118 :end-before: >8 End of a new mempool in memory to hold the mbufs. 119 :dedent: 1 120 121Mbufs are the packet buffer structure used by DPDK. They are explained in 122detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*. 123 124The ``main()`` function also initializes all the ports using the user defined 125``port_init()`` function with portmask provided by user: 126 127.. literalinclude:: ../../../examples/ptpclient/ptpclient.c 128 :language: c 129 :start-after: Initialize all ports. 8< 130 :end-before: >8 End of initialization of all ports. 131 :dedent: 1 132 133 134Once the initialization is complete, the application is ready to launch a 135function on an lcore. In this example ``lcore_main()`` is called on a single 136lcore. 137 138.. code-block:: c 139 140 lcore_main(); 141 142The ``lcore_main()`` function is explained below. 143 144 145The Lcores Main 146~~~~~~~~~~~~~~~ 147 148As we saw above the ``main()`` function calls an application function on the 149available lcores. 150 151The main work of the application is done within the loop: 152 153.. literalinclude:: ../../../examples/ptpclient/ptpclient.c 154 :language: c 155 :start-after: Read packet from RX queues. 8< 156 :end-before: >8 End of read packets from RX queues. 157 :dedent: 2 158 159Packets are received one by one on the RX ports and, if required, PTP response 160packets are transmitted on the TX ports. 161 162If the offload flags in the mbuf indicate that the packet is a PTP packet then 163the packet is parsed to determine which type: 164 165.. literalinclude:: ../../../examples/ptpclient/ptpclient.c 166 :language: c 167 :start-after: Packet is parsed to determine which type. 8< 168 :end-before: >8 End of packet is parsed to determine which type. 169 :dedent: 3 170 171 172All packets are freed explicitly using ``rte_pktmbuf_free()``. 173 174The forwarding loop can be interrupted and the application closed using 175``Ctrl-C``. 176 177 178PTP parsing 179~~~~~~~~~~~ 180 181The ``parse_ptp_frames()`` function processes PTP packets, implementing time receiver 182PTP IEEE1588 L2 functionality. 183 184.. literalinclude:: ../../../examples/ptpclient/ptpclient.c 185 :language: c 186 :start-after: Parse ptp frames. 8< 187 :end-before: >8 End of function processes PTP packets. 188 189There are 3 types of packets on the RX path which we must parse to create a minimal 190implementation of the PTP time receiver client: 191 192* SYNC packet. 193* FOLLOW UP packet 194* DELAY RESPONSE packet. 195 196When we parse the *FOLLOW UP* packet we also create and send a *DELAY_REQUEST* packet. 197Also when we parse the *DELAY RESPONSE* packet, and all conditions are met 198we adjust the PTP time receiver clock. 199