1.. zephyr:code-sample:: latmon-client
2   :name: Latmon Client
3   :relevant-api: latmon
4
5   Measures delta time between GPIO events and reports the latency metrics via latmon to the latmus
6   service executing on the SUT.
7
8Overview
9********
10
11This project provides tools to measure the worst-case response time of a system under test (SUT) to
12GPIO events using:
13
14- **Latmon**:
15
16  Runs on a Zephyr-based board to generate and monitor GPIO events while collecting metrics
17
18- **Latmus**:
19
20  Runs on the SUT to respond to the falling edge of input GPIO event, displaying the latency metrics
21  and generate histogram data.
22
23This project is part of the open-source initiative
24`EVL Project - Latmus GPIO Response Time <https://evlproject.org/core/benchmarks/#latmus-gpio-response-time>`_.
25
26The main program is designed to monitor latency using GPIO pins on a Zephyr-based system. It generates a
27pulse signal on a GPIO pin and measures the time it takes for the SUT (executing Latmus) to respond to
28it.
29
30The SUT must be running Latmus to capture the latency metrics and histogram information reported over the
31network. The program uses LEDs to indicate the different states, such as DHCP binding(red), waiting for the
32Latmus connection (blue) and sampling (green).
33
34Why Not Just Use a Timer?
35=========================
36
37Timer tests miss external factors like GPIO signals, hardware, and interrupt handling.
38Latmon and Latmus simulate real-world scenarios, capturing end-to-end latency metrics.
39This ensures accurate assessment of real-time responsiveness across the entire system.
40
41- **Real-Time Thread Testing**:
42
43  Evaluates how a user-space thread processes external interrupts.
44
45- **End-to-End Latency Measurement**:
46
47  Captures delays from hardware, drivers, and user-space threads.
48
49- **Versatile Platform Support**:
50
51  Works on EVL, PREEMPT_RT, and other platforms.
52
53Code Structure
54==============
55
56The Latmon sample application is divided into two main components:
57
58- **Application Logic** (:zephyr_file:`samples/net/latmon/src/main.c`):
59
60   This file contains the application logic for Latmon.
61   It initializes networking, provides the instrumentation mechanism and handles LED indicators for the
62   different states.
63
64- **Library** (:zephyr_file:`subsys/net/lib/latmon/latmon.c`):
65
66   This file provides reusable functions and abstractions for latency monitoring via Latmus.
67   It includes the core logic for reporting latency metrics and histogram data.
68
69Requirements
70************
71
72- **Zephyr-Compatible Board**:
73
74  A board with external GPIO support and an IPv4 network interface (e.g., FRDM-K64F).
75
76- **System under Test**:
77
78  A system with external GPIO pins running the Latmus service and an IPv4 network interface.
79
80- **Network Connection**:
81
82  A DHCP server for IP assignment.
83
84- **Physical Connection**:
85
86  GPIO wires connecting the Zephyr board to the SUT and both systems connected to the network.
87
88Setup and Usage
89***************
90
91- **Flash Latmon onto the Zephyr board**:
92
93  The application will connect to the network and wait for a connection from the SUT. The application
94  will use DHCP to obtain an IPv4 address.
95
96- **Connect GPIO pins for transmit (Zephyr to SUT) and receive (SUT to Zephyr)**
97
98  On **FRDM-K64F**, the sample code uses the **Arduino header J2**, ``pin 20`` for transmit the pulse to
99  the SUT and ``pin 18`` to receive the acknowledgment from the SUT.
100
101- **Run Latmus on the SUT**
102
103  Request the appropriate options with `Latmus <https://evlproject.org/core/testing/#latmus-program>`_. Users
104  can for example modify the sampling period with the ``-p`` option or generate historgram data for
105  postprocessing with the ``-g`` option,
106
107- **Monitor results from the SUT**
108
109  Latmus will report latency figures and, if requested, generate the histogram data file.
110
111- **Calibrating the Latmus latencies: CONFIG_LATMON_LOOPBACK_CALIBRATION**:
112
113  Users can connect the GPIO pins in loopback mode (transmit to ack) and build the Latmon sample application with
114  CONFIG_LATMON_LOOPBACK_CALIBRATION enabled. When connecting to Latmus in this configuration, Latmus is providing
115  a calibration value that can be used to adjust the final latencies.
116
117Example
118=======
119
120On the host and to build and flash the Zephyr FRDM-K64F board with the Latmon sample:
121
122.. code-block:: console
123
124   user@host:~$ west build -b frdm_k64f samples/net/latmon
125   user@host:~$ west flash
126
127On the SUT running on Linux, latmus **MUST** track the falling edge of the signal:
128
129.. code-block:: console
130
131   root@target:~$ latmus -I gpiochip2,23,falling-edge -O gpiochip2,21 -z -g"histogram" "broadcast"
132
133Monitoring both consoles, you should see the following:
134
135.. code-block:: console
136
137  [00:00:03.311,000] <inf> phy_mc_ksz8081: PHY 0 is up
138  [00:00:03.311,000] <inf> phy_mc_ksz8081: PHY (0) Link speed 100 Mb, full duplex
139  [00:00:03.312,000] <inf> eth_nxp_enet_mac: Link is up
140  *** Booting Zephyr OS build v4.1.0-3337-g886443a190b1 ***
141  [00:00:03.313,000] <inf> sample_latmon: DHCPv4: binding...
142  [00:00:03.313,000] <inf> latmon: Latmon server thread priority: 14
143  [00:00:10.964,000] <inf> net_dhcpv4: Received: 192.168.1.58
144  [00:00:10.964,000] <inf> sample_latmon: Listening on 192.168.1.58
145  [00:00:30.966,000] <inf> latmon: Waiting for Latmus ...
146  [00:00:31.356,000] <inf> latmon: Monitor thread priority: -16
147  [00:00:31.356,000] <inf> latmon:        monitoring started:
148  [00:00:31.356,000] <inf> latmon:         - samples per period: 1000
149  [00:00:31.356,000] <inf> latmon:         - period: 1000 usecs
150  [00:00:31.356,000] <inf> latmon:         - histogram cells: 200
151  [00:00:31.393,000] <inf> latmon: Transfer thread priority: 14
152
153.. code-block:: console
154
155  root@target:~$ latmus -I gpiochip2,23,falling-edge -O gpiochip2,21 -Z -g"histogram" broadcast
156  Received broadcast message: 192.168.1.58
157  warming up on CPU0 (not isolated)...
158  connecting to latmon at 192.168.1.58:2306...
159  RTT|  00:00:16  (oob-gpio, 1000 us period, priority 98, CPU0-noisol)
160  RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst
161  RTD|     26.375|     30.839|     33.508|       0|     0|     26.375|     33.508
162  RTD|     26.333|     30.801|     37.633|       0|     0|     26.333|     37.633
163  RTD|     26.375|     30.801|     31.966|       0|     0|     26.333|     37.633
164  RTD|     26.375|     30.911|     49.675|       0|     0|     26.333|     49.675
165  RTD|     26.333|     30.830|     41.658|       0|     0|     26.333|     49.675
166  RTD|     26.375|     31.107|     59.216|       0|     0|     26.333|     59.216
167  RTD|     26.333|     30.767|     30.925|       0|     0|     26.333|     59.216
168  RTD|     26.333|     30.781|     41.616|       0|     0|     26.333|     59.216
169  RTD|     26.375|     30.768|     32.925|       0|     0|     26.333|     59.216
170  RTD|     26.375|     30.768|     37.633|       0|     0|     26.333|     59.216
171
172On completion and from your host, retrieve the histogram file from the SUT, and generate a plot (a PNG file) using
173gnuplot:
174
175.. code-block:: console
176
177   user@host:~$ gnuplot plot_data.gp
178
179The ``plot_data.gp`` script should look like this for a file named ``histogram``:
180
181.. code-block:: gnuplot
182
183   set terminal pngcairo size 800,600
184   set output 'plot.png'
185   set title "Data Plot"
186   set xlabel "Latency (usec)"
187   set ylabel "Sample Count"
188   set grid
189   set style data linespoints
190   plot 'histogram' using 1:2 with linespoints title "Data Points"
191