|
| 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 | + |
| 8 | +Overview |
| 9 | +******** |
| 10 | + |
| 11 | +This project provides tools to measure the worst-case response time of a system under test (SUT) to |
| 12 | +GPIO 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 | + |
| 23 | +This 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 | + |
| 26 | +The main program is designed to monitor latency using GPIO pins on a Zephyr-based system. It generates a |
| 27 | +pulse signal on a GPIO pin and measures the time it takes for the SUT (executing Latmus) to respond to |
| 28 | +it. |
| 29 | + |
| 30 | +The SUT must be running Latmus to capture the latency metrics and histogram information reported over the |
| 31 | +network. The program uses LEDs to indicate the different states, such as DHCP binding(red), waiting for the |
| 32 | +Latmus connection (blue) and sampling (green). |
| 33 | + |
| 34 | +Why Not Just Use a Timer? |
| 35 | +========================= |
| 36 | + |
| 37 | +Timer tests miss external factors like GPIO signals, hardware, and interrupt handling. |
| 38 | +Latmon and Latmus simulate real-world scenarios, capturing end-to-end latency metrics. |
| 39 | +This 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 | + |
| 53 | +Code Structure |
| 54 | +============== |
| 55 | + |
| 56 | +The Latmon sample application is divided into two main components: |
| 57 | + |
| 58 | +- **Application Logic** (:zephyr_file:`samples/net/latmon/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 | + |
| 69 | +Requirements |
| 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 | + |
| 88 | +Setup 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 | + |
| 117 | +Example |
| 118 | +======= |
| 119 | + |
| 120 | +On 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 | +
|
| 127 | +On 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 | +
|
| 133 | +Monitoring 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 | +
|
| 172 | +On completion and from your host, retrieve the histogram file from the SUT, and generate a plot (a PNG file) using |
| 173 | +gnuplot: |
| 174 | + |
| 175 | +.. code-block:: console |
| 176 | +
|
| 177 | + user@host:~$ gnuplot plot_data.gp |
| 178 | +
|
| 179 | +The ``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" |
0 commit comments