Latmon Client

Browse source code on GitHub

Overview

This project provides tools to measure the worst-case response time of a system under test (SUT) to GPIO events using:

  • Latmon:

    Runs on a Zephyr-based board to generate and monitor GPIO events while collecting metrics

  • Latmus:

    Runs on the SUT to respond to the falling edge of input GPIO event, displaying the latency metrics and generate histogram data.

This project is part of the open-source initiative EVL Project - Latmus GPIO Response Time.

The main program is designed to monitor latency using GPIO pins on a Zephyr-based system. It generates a pulse signal on a GPIO pin and measures the time it takes for the SUT (executing Latmus) to respond to it.

The SUT must be running Latmus to capture the latency metrics and histogram information reported over the network. The program uses LEDs to indicate the different states, such as DHCP binding(red), waiting for the Latmus connection (blue) and sampling (green).

Why Not Just Use a Timer?

Timer tests miss external factors like GPIO signals, hardware, and interrupt handling. Latmon and Latmus simulate real-world scenarios, capturing end-to-end latency metrics. This ensures accurate assessment of real-time responsiveness across the entire system.

  • Real-Time Thread Testing:

    Evaluates how a user-space thread processes external interrupts.

  • End-to-End Latency Measurement:

    Captures delays from hardware, drivers, and user-space threads.

  • Versatile Platform Support:

    Works on EVL, PREEMPT_RT, and other platforms.

Code Structure

The Latmon sample application is divided into two main components:

  • Application Logic (samples/net/latmon/src/main.c):

    This file contains the application logic for Latmon. It initializes networking, provides the instrumentation mechanism and handles LED indicators for the different states.

  • Library (subsys/net/lib/latmon/latmon.c):

    This file provides reusable functions and abstractions for latency monitoring via Latmus. It includes the core logic for reporting latency metrics and histogram data.

Requirements

  • Zephyr-Compatible Board:

    A board with external GPIO support and an IPv4 network interface (e.g., FRDM-K64F).

  • System under Test:

    A system with external GPIO pins running the Latmus service and an IPv4 network interface.

  • Network Connection:

    A DHCP server for IP assignment.

  • Physical Connection:

    GPIO wires connecting the Zephyr board to the SUT and both systems connected to the network.

Setup and Usage

  • Flash Latmon onto the Zephyr board:

    The application will connect to the network and wait for a connection from the SUT. The application will use DHCP to obtain an IPv4 address.

  • Connect GPIO pins for transmit (Zephyr to SUT) and receive (SUT to Zephyr)

    On FRDM-K64F, the sample code uses the Arduino header J2, pin 20 for transmit the pulse to the SUT and pin 18 to receive the acknowledgment from the SUT.

  • Run Latmus on the SUT

    Request the appropriate options with Latmus. Users can for example modify the sampling period with the -p option or generate historgram data for postprocessing with the -g option,

  • Monitor results from the SUT

    Latmus will report latency figures and, if requested, generate the histogram data file.

  • Calibrating the Latmus latencies: CONFIG_LATMON_LOOPBACK_CALIBRATION:

    Users can connect the GPIO pins in loopback mode (transmit to ack) and build the Latmon sample application with CONFIG_LATMON_LOOPBACK_CALIBRATION enabled. When connecting to Latmus in this configuration, Latmus is providing a calibration value that can be used to adjust the final latencies.

Example

On the host and to build and flash the Zephyr FRDM-K64F board with the Latmon sample:

user@host:~$ west build -b frdm_k64f samples/net/latmon
user@host:~$ west flash

On the SUT running on Linux, latmus MUST track the falling edge of the signal:

root@target:~$ latmus -I gpiochip2,23,falling-edge -O gpiochip2,21 -z -g"histogram" "broadcast"

Monitoring both consoles, you should see the following:

[00:00:03.311,000] <inf> phy_mc_ksz8081: PHY 0 is up
[00:00:03.311,000] <inf> phy_mc_ksz8081: PHY (0) Link speed 100 Mb, full duplex
[00:00:03.312,000] <inf> eth_nxp_enet_mac: Link is up
*** Booting Zephyr OS build v4.1.0-3337-g886443a190b1 ***
[00:00:03.313,000] <inf> sample_latmon: DHCPv4: binding...
[00:00:03.313,000] <inf> latmon: Latmon server thread priority: 14
[00:00:10.964,000] <inf> net_dhcpv4: Received: 192.168.1.58
[00:00:10.964,000] <inf> sample_latmon: Listening on 192.168.1.58
[00:00:30.966,000] <inf> latmon: Waiting for Latmus ...
[00:00:31.356,000] <inf> latmon: Monitor thread priority: -16
[00:00:31.356,000] <inf> latmon:        monitoring started:
[00:00:31.356,000] <inf> latmon:         - samples per period: 1000
[00:00:31.356,000] <inf> latmon:         - period: 1000 usecs
[00:00:31.356,000] <inf> latmon:         - histogram cells: 200
[00:00:31.393,000] <inf> latmon: Transfer thread priority: 14
root@target:~$ latmus -I gpiochip2,23,falling-edge -O gpiochip2,21 -Z -g"histogram" broadcast
Received broadcast message: 192.168.1.58
warming up on CPU0 (not isolated)...
connecting to latmon at 192.168.1.58:2306...
RTT|  00:00:16  (oob-gpio, 1000 us period, priority 98, CPU0-noisol)
RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst
RTD|     26.375|     30.839|     33.508|       0|     0|     26.375|     33.508
RTD|     26.333|     30.801|     37.633|       0|     0|     26.333|     37.633
RTD|     26.375|     30.801|     31.966|       0|     0|     26.333|     37.633
RTD|     26.375|     30.911|     49.675|       0|     0|     26.333|     49.675
RTD|     26.333|     30.830|     41.658|       0|     0|     26.333|     49.675
RTD|     26.375|     31.107|     59.216|       0|     0|     26.333|     59.216
RTD|     26.333|     30.767|     30.925|       0|     0|     26.333|     59.216
RTD|     26.333|     30.781|     41.616|       0|     0|     26.333|     59.216
RTD|     26.375|     30.768|     32.925|       0|     0|     26.333|     59.216
RTD|     26.375|     30.768|     37.633|       0|     0|     26.333|     59.216

On completion and from your host, retrieve the histogram file from the SUT, and generate a plot (a PNG file) using gnuplot:

user@host:~$ gnuplot plot_data.gp

The plot_data.gp script should look like this for a file named histogram:

set terminal pngcairo size 800,600
set output 'plot.png'
set title "Data Plot"
set xlabel "Latency (usec)"
set ylabel "Sample Count"
set grid
set style data linespoints
plot 'histogram' using 1:2 with linespoints title "Data Points"

See also

Latency Monitor