xref: /dpdk/doc/guides/sample_app_ug/ptpclient.rst (revision 5357e228f3fc9db861a45fa512db6decfb29352b)
15630257fSFerruh Yigit..  SPDX-License-Identifier: BSD-3-Clause
25630257fSFerruh Yigit    Copyright(c) 2015 Intel Corporation.
32d123257SDaniel Mrzyglod
42d123257SDaniel MrzyglodPTP Client Sample Application
52d123257SDaniel Mrzyglod=============================
62d123257SDaniel Mrzyglod
72d123257SDaniel MrzyglodThe PTP (Precision Time Protocol) client sample application is a simple
8b8d1d60fSStephen Hemmingerexample of using the DPDK IEEE1588 API to communicate with a PTP time transmitter
92d123257SDaniel Mrzyglodto synchronize the time on the NIC and, optionally, on the Linux system.
102d123257SDaniel Mrzyglod
112d123257SDaniel MrzyglodNote, PTP is a time syncing protocol and cannot be used within DPDK as a
122d123257SDaniel Mrzyglodtime-stamping mechanism. See the following for an explanation of the protocol:
132d123257SDaniel Mrzyglod`Precision Time Protocol
142d123257SDaniel Mrzyglod<https://en.wikipedia.org/wiki/Precision_Time_Protocol>`_.
152d123257SDaniel Mrzyglod
162d123257SDaniel Mrzyglod
172d123257SDaniel MrzyglodLimitations
182d123257SDaniel Mrzyglod-----------
192d123257SDaniel Mrzyglod
202d123257SDaniel MrzyglodThe PTP sample application is intended as a simple reference implementation of
212d123257SDaniel Mrzygloda PTP client using the DPDK IEEE1588 API.
222d123257SDaniel MrzyglodIn order to keep the application simple the following assumptions are made:
232d123257SDaniel Mrzyglod
24b8d1d60fSStephen Hemminger* The first discovered time transmitter is the main for the session.
252d123257SDaniel Mrzyglod* Only L2 PTP packets are supported.
262d123257SDaniel Mrzyglod* Only the PTP v2 protocol is supported.
27b8d1d60fSStephen Hemminger* Only the time receiver clock is implemented.
282d123257SDaniel Mrzyglod
292d123257SDaniel Mrzyglod
302d123257SDaniel MrzyglodHow the Application Works
312d123257SDaniel Mrzyglod-------------------------
322d123257SDaniel Mrzyglod
332d123257SDaniel Mrzyglod.. _figure_ptpclient_highlevel:
342d123257SDaniel Mrzyglod
352d123257SDaniel Mrzyglod.. figure:: img/ptpclient.*
362d123257SDaniel Mrzyglod
372d123257SDaniel Mrzyglod   PTP Synchronization Protocol
382d123257SDaniel Mrzyglod
392d123257SDaniel MrzyglodThe PTP synchronization in the sample application works as follows:
402d123257SDaniel Mrzyglod
41b8d1d60fSStephen Hemminger* Time transmitter sends *Sync* message - the time receiver saves it as T2.
42b8d1d60fSStephen Hemminger* Time transmitter sends *Follow Up* message and sends time of T1.
43b8d1d60fSStephen Hemminger* Time receiver sends *Delay Request* frame to PTP time transmitter and stores T3.
44b8d1d60fSStephen Hemminger* Time transmitter sends *Delay Response* T4 time which is time of received T3.
452d123257SDaniel Mrzyglod
46b8d1d60fSStephen HemmingerThe adjustment for time receiver can be represented as:
472d123257SDaniel Mrzyglod
482d123257SDaniel Mrzyglod   adj = -[(T2-T1)-(T4 - T3)]/2
492d123257SDaniel Mrzyglod
502d123257SDaniel MrzyglodIf the command line parameter ``-T 1`` is used the application also
512d123257SDaniel Mrzyglodsynchronizes the PTP PHC clock with the Linux kernel clock.
522d123257SDaniel Mrzyglod
532d123257SDaniel MrzyglodCompiling the Application
542d123257SDaniel Mrzyglod-------------------------
552d123257SDaniel Mrzyglod
567cacb056SHerakliusz LipiecTo compile the sample application see :doc:`compiling`.
577cacb056SHerakliusz Lipiec
587cacb056SHerakliusz LipiecThe application is located in the ``ptpclient`` sub-directory.
597cacb056SHerakliusz Lipiec
602d123257SDaniel Mrzyglod
612d123257SDaniel MrzyglodRunning the Application
622d123257SDaniel Mrzyglod-----------------------
632d123257SDaniel Mrzyglod
64218c4e68SBruce RichardsonTo run the example in a ``linux`` environment:
652d123257SDaniel Mrzyglod
662d123257SDaniel Mrzyglod.. code-block:: console
672d123257SDaniel Mrzyglod
68*5357e228SMingjin Ye    ./<build_dir>/examples/dpdk-ptpclient -l 1 -n 4 -- -p 0x1 -T 0
692d123257SDaniel Mrzyglod
702d123257SDaniel MrzyglodRefer to *DPDK Getting Started Guide* for general information on running
712d123257SDaniel Mrzyglodapplications and the Environment Abstraction Layer (EAL) options.
722d123257SDaniel Mrzyglod
732d123257SDaniel Mrzyglod* ``-p portmask``: Hexadecimal portmask.
74b8d1d60fSStephen Hemminger* ``-T 0``: Update only the PTP time receiver clock.
75b8d1d60fSStephen Hemminger* ``-T 1``: Update the PTP time receiver clock and synchronize the Linux Kernel to the PTP clock.
762d123257SDaniel Mrzyglod
772d123257SDaniel Mrzyglod
782d123257SDaniel MrzyglodCode Explanation
792d123257SDaniel Mrzyglod----------------
802d123257SDaniel Mrzyglod
812d123257SDaniel MrzyglodThe following sections provide an explanation of the main components of the
822d123257SDaniel Mrzyglodcode.
832d123257SDaniel Mrzyglod
842d123257SDaniel MrzyglodAll DPDK library functions used in the sample code are prefixed with ``rte_``
852d123257SDaniel Mrzyglodand are explained in detail in the *DPDK API Documentation*.
862d123257SDaniel Mrzyglod
872d123257SDaniel Mrzyglod
882d123257SDaniel MrzyglodThe Main Function
892d123257SDaniel Mrzyglod~~~~~~~~~~~~~~~~~
902d123257SDaniel Mrzyglod
912d123257SDaniel MrzyglodThe ``main()`` function performs the initialization and calls the execution
922d123257SDaniel Mrzyglodthreads for each lcore.
932d123257SDaniel Mrzyglod
942d123257SDaniel MrzyglodThe first task is to initialize the Environment Abstraction Layer (EAL).  The
952d123257SDaniel Mrzyglod``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()``
962d123257SDaniel Mrzyglodfunction. The value returned is the number of parsed arguments:
972d123257SDaniel Mrzyglod
989a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ptpclient/ptpclient.c
999a212dc0SConor Fogarty    :language: c
1009a212dc0SConor Fogarty    :start-after: Initialize the Environment Abstraction Layer (EAL). 8<
1019a212dc0SConor Fogarty    :end-before: >8 End of initialization of EAL.
1029a212dc0SConor Fogarty    :dedent: 1
1032d123257SDaniel Mrzyglod
1042d123257SDaniel MrzyglodAnd than we parse application specific arguments
1052d123257SDaniel Mrzyglod
1069a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ptpclient/ptpclient.c
1079a212dc0SConor Fogarty    :language: c
1089a212dc0SConor Fogarty    :start-after: Parse specific arguments. 8<
1099a212dc0SConor Fogarty    :end-before: >8 End of parsing specific arguments.
1109a212dc0SConor Fogarty    :dedent: 1
1112d123257SDaniel Mrzyglod
1122d123257SDaniel MrzyglodThe ``main()`` also allocates a mempool to hold the mbufs (Message Buffers)
1132d123257SDaniel Mrzyglodused by the application:
1142d123257SDaniel Mrzyglod
1159a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ptpclient/ptpclient.c
1169a212dc0SConor Fogarty    :language: c
1179a212dc0SConor Fogarty    :start-after: Creates a new mempool in memory to hold the mbufs. 8<
1189a212dc0SConor Fogarty    :end-before:  >8 End of a new mempool in memory to hold the mbufs.
1199a212dc0SConor Fogarty    :dedent: 1
1202d123257SDaniel Mrzyglod
1212d123257SDaniel MrzyglodMbufs are the packet buffer structure used by DPDK. They are explained in
1222d123257SDaniel Mrzygloddetail in the "Mbuf Library" section of the *DPDK Programmer's Guide*.
1232d123257SDaniel Mrzyglod
1242d123257SDaniel MrzyglodThe ``main()`` function also initializes all the ports using the user defined
1252d123257SDaniel Mrzyglod``port_init()`` function with portmask provided by user:
1262d123257SDaniel Mrzyglod
1279a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ptpclient/ptpclient.c
1289a212dc0SConor Fogarty    :language: c
1299a212dc0SConor Fogarty    :start-after: Initialize all ports. 8<
1309a212dc0SConor Fogarty    :end-before: >8 End of initialization of all ports.
1319a212dc0SConor Fogarty    :dedent: 1
1322d123257SDaniel Mrzyglod
1332d123257SDaniel Mrzyglod
1342d123257SDaniel MrzyglodOnce the initialization is complete, the application is ready to launch a
1352d123257SDaniel Mrzyglodfunction on an lcore. In this example ``lcore_main()`` is called on a single
1362d123257SDaniel Mrzyglodlcore.
1372d123257SDaniel Mrzyglod
1382d123257SDaniel Mrzyglod.. code-block:: c
1392d123257SDaniel Mrzyglod
1402d123257SDaniel Mrzyglod	lcore_main();
1412d123257SDaniel Mrzyglod
1422d123257SDaniel MrzyglodThe ``lcore_main()`` function is explained below.
1432d123257SDaniel Mrzyglod
1442d123257SDaniel Mrzyglod
1452d123257SDaniel MrzyglodThe Lcores Main
1462d123257SDaniel Mrzyglod~~~~~~~~~~~~~~~
1472d123257SDaniel Mrzyglod
1482d123257SDaniel MrzyglodAs we saw above the ``main()`` function calls an application function on the
1492d123257SDaniel Mrzyglodavailable lcores.
1502d123257SDaniel Mrzyglod
1512d123257SDaniel MrzyglodThe main work of the application is done within the loop:
1522d123257SDaniel Mrzyglod
1539a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ptpclient/ptpclient.c
1549a212dc0SConor Fogarty    :language: c
1559a212dc0SConor Fogarty    :start-after: Read packet from RX queues. 8<
1569a212dc0SConor Fogarty    :end-before: >8 End of read packets from RX queues.
1579a212dc0SConor Fogarty    :dedent: 2
1582d123257SDaniel Mrzyglod
1592d123257SDaniel MrzyglodPackets are received one by one on the RX ports and, if required, PTP response
1602d123257SDaniel Mrzyglodpackets are transmitted on the TX ports.
1612d123257SDaniel Mrzyglod
1622d123257SDaniel MrzyglodIf the offload flags in the mbuf indicate that the packet is a PTP packet then
1632d123257SDaniel Mrzyglodthe packet is parsed to determine which type:
1642d123257SDaniel Mrzyglod
1659a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ptpclient/ptpclient.c
1669a212dc0SConor Fogarty    :language: c
1679a212dc0SConor Fogarty    :start-after: Packet is parsed to determine which type. 8<
1689a212dc0SConor Fogarty    :end-before: >8 End of packet is parsed to determine which type.
1699a212dc0SConor Fogarty    :dedent: 3
1702d123257SDaniel Mrzyglod
1712d123257SDaniel Mrzyglod
1722d123257SDaniel MrzyglodAll packets are freed explicitly using ``rte_pktmbuf_free()``.
1732d123257SDaniel Mrzyglod
1742d123257SDaniel MrzyglodThe forwarding loop can be interrupted and the application closed using
1752d123257SDaniel Mrzyglod``Ctrl-C``.
1762d123257SDaniel Mrzyglod
1772d123257SDaniel Mrzyglod
1782d123257SDaniel MrzyglodPTP parsing
1792d123257SDaniel Mrzyglod~~~~~~~~~~~
1802d123257SDaniel Mrzyglod
181b8d1d60fSStephen HemmingerThe ``parse_ptp_frames()`` function processes PTP packets, implementing time receiver
1822d123257SDaniel MrzyglodPTP IEEE1588 L2 functionality.
1832d123257SDaniel Mrzyglod
1849a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ptpclient/ptpclient.c
1859a212dc0SConor Fogarty    :language: c
1869a212dc0SConor Fogarty    :start-after: Parse ptp frames. 8<
1879a212dc0SConor Fogarty    :end-before:  >8 End of function processes PTP packets.
1882d123257SDaniel Mrzyglod
1892d123257SDaniel MrzyglodThere are 3 types of packets on the RX path which we must parse to create a minimal
190b8d1d60fSStephen Hemmingerimplementation of the PTP time receiver client:
1912d123257SDaniel Mrzyglod
1922d123257SDaniel Mrzyglod* SYNC packet.
1932d123257SDaniel Mrzyglod* FOLLOW UP packet
1942d123257SDaniel Mrzyglod* DELAY RESPONSE packet.
1952d123257SDaniel Mrzyglod
1962d123257SDaniel MrzyglodWhen we parse the *FOLLOW UP* packet we also create and send a *DELAY_REQUEST* packet.
197b8d1d60fSStephen HemmingerAlso when we parse the *DELAY RESPONSE* packet, and all conditions are met
198b8d1d60fSStephen Hemmingerwe adjust the PTP time receiver clock.
199