How to run OPC UA stack open62541 with
Realtime PubSub on Realtime Linux and TSN
using Intel i210 ethernet card

 

This quick start guide serves as a starting point for a user in learning/evaluating OPC UA including TSN technology
for their products/projects.

This quick start guide uses “Open Source OPC UA stack open62541 with Pub/Sub feature” and leverages the TSN features
available on “standard Linux kernel + PREMPT_RT patches” on an X86 PC hardware with intel i210 Ethernet Card

 

Prerequisites

 

Hardware requirement:

2 numbers of 4 core Intel X86 processor PCs (at least Apollolake processor) with i210 network interface cards

The 2 nodes can be setup in any of the two different network as shown below

QSG_test_setup  

Software requirement:

Lubuntu 18.04 (We used Lubuntu for our test setup, however the steps given below should work with any Ubuntu distribution).

After installing the OS give the following command to update the system

apt get update && apt get upgrade
 

Preempt RT kernel 4.19.37-rt19 can be downloaded with the following command

wget http://www.kernel.org/pub/linux/kernel/v4.x/linux-4.19.37.tar.xz
tar -Jxvf linux-4.19.37.tar.xz
 

RT patches required for the system can be then downloaded using the following command

cd linux-4.19.37
mkdir patches
cd patches
wget https://www.osadl.org/monitoring/patches/rds3/series
for i in `cat series`
do
  wget https://www.osadl.org/monitoring/patches/rds3/$i
done
 

Make sure to enable ETF and XDP sockets (also enable BPF STREAM PARSER feature under XDP sockets) before proceeding with the kernel build.
After the kernel is installed with RT patch, we verify that the system is realtime capable by running cyclictest to measure the maximum
latency of the system under nominal system and network load. For the test system that we used, the max latency measured was within the range of 50µs.

Configuring, building and tuning the RT kernel system to achieve minimal latency is beyond the scope of this quick start guide.

 

Environment setup

 

On your nodes, check if you have booted into the right kernel using the below given command

uname -r
 

The output of the above given command should return 4.19.37-rt19

RT Kernel  

In order to check whether the node is booted with RT patched kernel, use the following command:

uname -v
 

The output of the above given command should return PREEMPT RT

RT Preempt  

Packages required for configuring and running the application can be installed using the below given command

sudo apt-get install net-tools openssh-server make gcc libncurses5-dev bison flex libelf-dev irqbalance linuxptp daemonize libmbedtls-dev vlan libssl-dev cmake-curses-gui g++ gnuplot curl ethtool clang llvm -y
 

Disable accelerated graphics and enable frame buffer based graphic processing using the below given command

sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& nomodeset/' /etc/default/grub
sudo update-grub
 

Isolate CPU cores 1,2,3 from system task using the below given command

sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& isolcpus=1,2,3/' /etc/default/grub
sudo update-grub
 

Enable irqbalance to mask interrupts using the below given command

sudo sed -i '/IRQBALANCE_BANNED_CPUS=/c\IRQBALANCE_BANNED_CPUS=e' /etc/default/irqbalance
 

Clone and install iproute2 package version 4.19 using the below given commands

git clone https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
cd iproute2/
 

Checkout to the commit using the following command

git checkout e7d0b97f0544c02fef1185563def23114d7cfdd8
 

The commit message of the SHA of iproute2 used is as shown below

QSG_iproute2_commit_msg
 

Follow the steps given below to build iproute2

make all
make install
cd ../
 

Clone and install linux PTP package version 2.0 using the below given commands

git clone https://github.com/richardcochran/linuxptp.git
 
cd linuxptp/
 
git checkout -f 059269d0cc50f8543b00c3c1f52f33a6c1aa5912
 

The commit message of the SHA of linuxptp used is as shown below

QSG_linuxptp_commit_msg
 

To verify the PTP accuracy with master clock enter the below listed lines to add debug prints

sed -i '/clock_stats_update(&c->stats, tmv_dbl(c->master_offset), freq);/a pr_info("master offset %10" PRId64 " s%d freq %+7.0f " "path delay %9" PRId64,tmv_to_nanoseconds(c->master_offset), state, freq, tmv_to_nanoseconds(c->path_delay));' clock.c
sed -i '/clock_stats_update(&c->stats, tmv_dbl(c->master_offset), adj);/a pr_info("master offset %10" PRId64 " s%d freq %+7.0f " "path delay %9" PRId64,tmv_to_nanoseconds(c->master_offset), state, adj, tmv_to_nanoseconds(c->path_delay));' clock.c
sed -i '/if (!stats_get_result(s->delay, &delay_stats)) {/a/*' clock.c
sed -i '/delay_stats.mean, delay_stats.stddev);/a*/' clock.c
 

Install the application following the given steps below

make
make install
cp configs/gPTP.cfg /etc/linuxptp/
cd ../
 

Clone and install bpf-next package for Linux 4.19 using the below given commands

cd /usr/src/
 
git clone https://github.com/xdp-project/bpf-next.git
 
cd bpf-next/
 
git checkout 84df9525b0c27f3ebc2ebb1864fa62a97fdedb7d
 

The commit message of the SHA of bpf-next used is as shown below

QSG_bpf-next_commit_msg
 
make defconfig
make headers_install
cd samples/bpf
make
 

Check if the /etc/modules already has entry for 8021q

cat /etc/modules | grep '8021q'
 

If the above command does not return anything, then add

echo "8021q" >> /etc/modules
 

Setup static IP address for PubSub communication interface

vi /etc/netplan/01-network-manager-all.yaml
 

Copy paste the following lines and replace “X” with a suitable suffix number to setup IP address for PubSub interface

In our case the interface name is enp2s0, replace this with your i210 interface name

Note: Make sure to configure different suffix addresses for the two nodes

Example: Node 1 IP address: 192.168.0.1, Node 2 IP address: 192.168.0.2

network:
  version: 2
  ethernets:
      enp2s0:
          dhcp4: false
          dhcp6: false
          addresses:
          - 192.168.0.X/24
  vlans:
      enp2s0.1:
          id: 1
          link: enp2s0
          addresses:
          - 192.168.1.X/24
      enp2s0.2:
          id: 2
          link: enp2s0
          addresses:
          - 192.168.2.X/24
      enp2s0.3:
          id: 3
          link: enp2s0
          addresses:
          - 192.168.3.X/24
      enp2s0.4:
          id: 4
          link: enp2s0
          addresses:
          - 192.168.4.X/24
      enp2s0.5:
          id: 5
          link: enp2s0
          addresses:
          - 192.168.5.X/24
      enp2s0.6:
          id: 6
          link: enp2s0
          addresses:
          - 192.168.6.X/24
      enp2s0.7:
          id: 7
          link: enp2s0
          addresses:
          - 192.168.7.X/24
      enp2s0.8:
          id: 8
          link: enp2s0
          addresses:
          - 192.168.8.X/24

 

Generate and apply the netplan by using the following commands

netplan generate
 
netplan apply
 

Verify that the configured IP address is set by giving the following command

ifconfig
 

Create Bootup script

vi /etc/rc.local
   

Copy paste the below given lines

#!/bin/bash
  #Verify if 8021q module is loaded
lsmod | grep '8021q' > /var/log/rc.local.log

sleep 3

#Get the interface name for the i210 card to be configured for TSN
#This will throw error if netplan is not set as specified in QSG modify the line below in case you wanted to run the application in a different IP address
IFACE=`sudo ifconfig | grep -B1 192.168.0 | cut -d ':' -f1 | head -1`

################################################################################
# Configure transmit
################################################################################

#Clean up any existing setting
sudo tc qdisc del dev $IFACE root

#Configure ETF
sudo tc qdisc add dev $IFACE parent root mqprio num_tc 3 map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 1@0 1@1 2@2 hw 0

MQPRIO_NUM=`sudo tc qdisc show | grep mqprio | cut -d ':' -f1 | cut -d ' ' -f3`
sudo tc qdisc add dev $IFACE parent $MQPRIO_NUM:1 etf offload clockid CLOCK_TAI delta 150000
sudo tc qdisc add dev $IFACE parent $MQPRIO_NUM:2 etf offload clockid CLOCK_TAI delta 150000

################################################################################
# Configure receive
################################################################################

ethtool --show-features $IFACE | grep ntup >> /var/log/rc.local.log
ethtool --show-ntuple $IFACE >> /var/log/rc.local.log

#Configure Multicast MAC

#1. We should disable promiscuous multicast

#2. We should have an exact match of the multicast address of incoming frame
# with Multicast Filter Address (MFA) see section 7.1.1.1.2 of i210 datasheet.

#Disable promiscuous mode
ip link set $IFACE promisc off

#Enable ntuple feature
ethtool -K $IFACE ntuple on

#Delete pre-existing rules
ethtool --config-ntuple $IFACE delete 15
ethtool --config-ntuple $IFACE delete 14

#Add rules for Multicast MAC addresses
ethtool --config-ntuple $IFACE flow-type ether dst 01:00:5E:00:00:01 loc 15
ethtool --config-ntuple $IFACE flow-type ether dst 01:00:5E:7F:00:01 loc 14

ethtool --show-features $IFACE | grep ntup >> /var/log/rc.local.log
ethtool --show-ntuple $IFACE >> /var/log/rc.local.log

#Packet can go to VLAN filtering stage only after the MFA pass
#Delete pre-existing ingress policy if there is any
tc qdisc delete dev $IFACE ingress

#Add ingress policy for the interface
tc qdisc add dev $IFACE ingress

#Steer the incomming packets with specified destination MAC to ingress queue 2
tc filter add dev $IFACE parent ffff: proto 0xb62c flower dst_mac 01:00:5E:00:00:01 hw_tc 2 skip_sw
tc filter add dev $IFACE parent ffff: proto 0xb62c flower dst_mac 01:00:5E:7F:00:01 hw_tc 2 skip_sw

#Configure equal weightage to queue 0 and 1
ethtool -X $IFACE equal 2

#Disable VLAN offload
ethtool -K $IFACE rxvlan off

sleep 3

#Configure ingress mapping
sudo vconfig set_ingress_map $IFACE.1 0 0
sudo vconfig set_ingress_map $IFACE.1 1 1
sudo vconfig set_ingress_map $IFACE.1 2 2
sudo vconfig set_ingress_map $IFACE.1 3 3
sudo vconfig set_ingress_map $IFACE.1 4 4
sudo vconfig set_ingress_map $IFACE.1 5 5
sudo vconfig set_ingress_map $IFACE.1 6 6
sudo vconfig set_ingress_map $IFACE.1 7 7

sudo vconfig set_ingress_map $IFACE.2 0 0
sudo vconfig set_ingress_map $IFACE.2 1 1
sudo vconfig set_ingress_map $IFACE.2 2 2
sudo vconfig set_ingress_map $IFACE.2 3 3
sudo vconfig set_ingress_map $IFACE.2 4 4
sudo vconfig set_ingress_map $IFACE.2 5 5
sudo vconfig set_ingress_map $IFACE.2 6 6
sudo vconfig set_ingress_map $IFACE.2 7 7

sudo vconfig set_ingress_map $IFACE.3 0 0
sudo vconfig set_ingress_map $IFACE.3 1 1
sudo vconfig set_ingress_map $IFACE.3 2 2
sudo vconfig set_ingress_map $IFACE.3 3 3
sudo vconfig set_ingress_map $IFACE.3 4 4
sudo vconfig set_ingress_map $IFACE.3 5 5
sudo vconfig set_ingress_map $IFACE.3 6 6
sudo vconfig set_ingress_map $IFACE.3 7 7

sudo vconfig set_ingress_map $IFACE.4 0 0
sudo vconfig set_ingress_map $IFACE.4 1 1
sudo vconfig set_ingress_map $IFACE.4 2 2
sudo vconfig set_ingress_map $IFACE.4 3 3
sudo vconfig set_ingress_map $IFACE.4 4 4
sudo vconfig set_ingress_map $IFACE.4 5 5
sudo vconfig set_ingress_map $IFACE.4 6 6
sudo vconfig set_ingress_map $IFACE.4 7 7

sudo vconfig set_ingress_map $IFACE.5 0 0
sudo vconfig set_ingress_map $IFACE.5 1 1
sudo vconfig set_ingress_map $IFACE.5 2 2
sudo vconfig set_ingress_map $IFACE.5 3 3
sudo vconfig set_ingress_map $IFACE.5 4 4
sudo vconfig set_ingress_map $IFACE.5 5 5
sudo vconfig set_ingress_map $IFACE.5 6 6
sudo vconfig set_ingress_map $IFACE.5 7 7

sudo vconfig set_ingress_map $IFACE.6 0 0
sudo vconfig set_ingress_map $IFACE.6 1 1
sudo vconfig set_ingress_map $IFACE.6 2 2
sudo vconfig set_ingress_map $IFACE.6 3 3
sudo vconfig set_ingress_map $IFACE.6 4 4
sudo vconfig set_ingress_map $IFACE.6 5 5
sudo vconfig set_ingress_map $IFACE.6 6 6
sudo vconfig set_ingress_map $IFACE.6 7 7

sudo vconfig set_ingress_map $IFACE.7 0 0
sudo vconfig set_ingress_map $IFACE.7 1 1
sudo vconfig set_ingress_map $IFACE.7 2 2
sudo vconfig set_ingress_map $IFACE.7 3 3
sudo vconfig set_ingress_map $IFACE.7 4 4
sudo vconfig set_ingress_map $IFACE.7 5 5
sudo vconfig set_ingress_map $IFACE.7 6 6
sudo vconfig set_ingress_map $IFACE.7 7 7

sudo vconfig set_ingress_map $IFACE.8 0 0
sudo vconfig set_ingress_map $IFACE.8 1 1
sudo vconfig set_ingress_map $IFACE.8 2 2
sudo vconfig set_ingress_map $IFACE.8 3 3
sudo vconfig set_ingress_map $IFACE.8 4 4
sudo vconfig set_ingress_map $IFACE.8 5 5
sudo vconfig set_ingress_map $IFACE.8 6 6
sudo vconfig set_ingress_map $IFACE.8 7 7

#Configure egress mapping
sudo vconfig set_egress_map $IFACE.1 0 0
sudo vconfig set_egress_map $IFACE.1 1 1
sudo vconfig set_egress_map $IFACE.1 2 2
sudo vconfig set_egress_map $IFACE.1 3 3
sudo vconfig set_egress_map $IFACE.1 4 4
sudo vconfig set_egress_map $IFACE.1 5 5
sudo vconfig set_egress_map $IFACE.1 6 6
sudo vconfig set_egress_map $IFACE.1 7 7

sudo vconfig set_egress_map $IFACE.2 0 0
sudo vconfig set_egress_map $IFACE.2 1 1
sudo vconfig set_egress_map $IFACE.2 2 2
sudo vconfig set_egress_map $IFACE.2 3 3
sudo vconfig set_egress_map $IFACE.2 4 4
sudo vconfig set_egress_map $IFACE.2 5 5
sudo vconfig set_egress_map $IFACE.2 6 6
sudo vconfig set_egress_map $IFACE.2 7 7

sudo vconfig set_egress_map $IFACE.3 0 0
sudo vconfig set_egress_map $IFACE.3 1 1
sudo vconfig set_egress_map $IFACE.3 2 2
sudo vconfig set_egress_map $IFACE.3 3 3
sudo vconfig set_egress_map $IFACE.3 4 4
sudo vconfig set_egress_map $IFACE.3 5 5
sudo vconfig set_egress_map $IFACE.3 6 6
sudo vconfig set_egress_map $IFACE.3 7 7

sudo vconfig set_egress_map $IFACE.4 0 0
sudo vconfig set_egress_map $IFACE.4 1 1
sudo vconfig set_egress_map $IFACE.4 2 2
sudo vconfig set_egress_map $IFACE.4 3 3
sudo vconfig set_egress_map $IFACE.4 4 4
sudo vconfig set_egress_map $IFACE.4 5 5
sudo vconfig set_egress_map $IFACE.4 6 6
sudo vconfig set_egress_map $IFACE.4 7 7

sudo vconfig set_egress_map $IFACE.5 0 0
sudo vconfig set_egress_map $IFACE.5 1 1
sudo vconfig set_egress_map $IFACE.5 2 2
sudo vconfig set_egress_map $IFACE.5 3 3
sudo vconfig set_egress_map $IFACE.5 4 4
sudo vconfig set_egress_map $IFACE.5 5 5
sudo vconfig set_egress_map $IFACE.5 6 6
sudo vconfig set_egress_map $IFACE.5 7 7

sudo vconfig set_egress_map $IFACE.6 0 0
sudo vconfig set_egress_map $IFACE.6 1 1
sudo vconfig set_egress_map $IFACE.6 2 2
sudo vconfig set_egress_map $IFACE.6 3 3
sudo vconfig set_egress_map $IFACE.6 4 4
sudo vconfig set_egress_map $IFACE.6 5 5
sudo vconfig set_egress_map $IFACE.6 6 6
sudo vconfig set_egress_map $IFACE.6 7 7

sudo vconfig set_egress_map $IFACE.7 0 0
sudo vconfig set_egress_map $IFACE.7 1 1
sudo vconfig set_egress_map $IFACE.7 2 2
sudo vconfig set_egress_map $IFACE.7 3 3
sudo vconfig set_egress_map $IFACE.7 4 4
sudo vconfig set_egress_map $IFACE.7 5 5
sudo vconfig set_egress_map $IFACE.7 6 6
sudo vconfig set_egress_map $IFACE.7 7 7

sudo vconfig set_egress_map $IFACE.8 0 0
sudo vconfig set_egress_map $IFACE.8 1 1
sudo vconfig set_egress_map $IFACE.8 2 2
sudo vconfig set_egress_map $IFACE.8 3 3
sudo vconfig set_egress_map $IFACE.8 4 4
sudo vconfig set_egress_map $IFACE.8 5 5
sudo vconfig set_egress_map $IFACE.8 6 6
sudo vconfig set_egress_map $IFACE.8 7 7

echo "tc qdisc show" >> /var/log/rc.local.log
tc qdisc show >> /var/log/rc.local.log
echo ifconfig >> /var/log/rc.local.log
ifconfig >> /var/log/rc.local.log
echo cat /proc/net/vlan/$IFACE.x
cat /proc/net/vlan/$IFACE.1 >> /var/log/rc.local.log
cat /proc/net/vlan/$IFACE.2 >> /var/log/rc.local.log
cat /proc/net/vlan/$IFACE.3 >> /var/log/rc.local.log
cat /proc/net/vlan/$IFACE.4 >> /var/log/rc.local.log
cat /proc/net/vlan/$IFACE.5 >> /var/log/rc.local.log
cat /proc/net/vlan/$IFACE.6 >> /var/log/rc.local.log
cat /proc/net/vlan/$IFACE.7 >> /var/log/rc.local.log
cat /proc/net/vlan/$IFACE.8 >> /var/log/rc.local.log
################################################################################
# Tune Linux for best possible real-time behaviour
################################################################################

#Print the pre-existing mode of cpu
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor >> /var/log/rc.local.log
cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor >> /var/log/rc.local.log
cat /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor >> /var/log/rc.local.log
cat /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor >> /var/log/rc.local.log

#Configure the CPU to be in performance mode
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

#Print the mode of cpu after configuring it to be in performance mode
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor >> /var/log/rc.local.log
cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor >> /var/log/rc.local.log
cat /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor >> /var/log/rc.local.log
cat /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor >> /var/log/rc.local.log

#Disable Idle state in CPU
#TODO:
# In some bios versions we see cpu idle state and in others we don't see, we have to explore and fix

for i in /sys/devices/system/cpu/cpu*/cpuidle/state*/disable; do cat $i; done >> /var/log/rc.local.log
for i in `ls -1 /sys/devices/system/cpu/cpu*/cpuidle/state*/disable | sort -nr`; do echo 1 >$i; done
for i in /sys/devices/system/cpu/cpu*/cpuidle/state*/disable; do cat $i; done >> /var/log/rc.local.log

################################################################################
# Run PTP
################################################################################

#Kill PTP application if there is any pre-running PTP application
pkill -9 ptp4l
#Kill PHC2SYS application if there is any pre-running PHC2SYS application
pkill -9 phc2sys

sleep 3

#PTP MASTER
#sudo daemonize -E BUILD_ID=dontKillMe -o /var/log/ptp4l.log -e /var/log/ptp4l.err.log /usr/bin/taskset -c 1 chrt 90 /usr/local/sbin/ptp4l -i $IFACE -2 -mq -f /etc/linuxptp/gPTP.cfg --step_threshold=1 --fault_reset_interval=0 --announceReceiptTimeout=10

#By default the PCs are configured to run as PTP slave hence the step to run as PTP master is commented out
#PTP SLAVE
sudo daemonize -E BUILD_ID=dontKillMe -o /var/log/ptp4l.log -e /var/log/ptp4l.err.log /usr/bin/taskset -c 1 chrt 90 /usr/local/sbin/ptp4l -i $IFACE -2 -mq -s -f /etc/linuxptp/gPTP.cfg --step_threshold=1 --fault_reset_interval=0 --announceReceiptTimeout=10
sudo pmc -u -b 0 -t 1 "SET GRANDMASTER_SETTINGS_NP clockClass 248 clockAccuracy 0xfe offsetScaledLogVariance 0xffff currentUtcOffset 37 leap61 0 leap59 0 currentUtcOffsetValid 1 ptpTimescale 1 timeTraceable 1 frequencyTraceable 0 timeSource 0xa0"
#PHC2SYS
sudo daemonize -E BUILD_ID=dontKillMe -o /var/log/phc2sys.log -e /var/log/phc2sys.err.log /usr/bin/taskset -c 1 chrt 89 /usr/local/sbin/phc2sys -s $IFACE -c CLOCK_REALTIME --step_threshold=1 --transportSpecific=1 -w -m

 

Note: By default the node is set to run as PTP slave. To run the node as PTP master, comment the PTP SLAVE section command and uncomment the PTP MASTER command

Save the script and modify the permission of the script to be executable during start up

chmod +x /etc/rc.local
   

Reboot the system to apply and verify the changes

sudo reboot
   

The output log of rc.local can be verified by giving the following command

cat /var/log/rc.local.log
 

The output log of PTP can be verified by giving the following command

tail -f /var/log/ptp4l.log
 

An example log file will look as shown below

QSG_ptp4l_log_slave  

The error log of PTP can be verified by giving the following command

tail -f /var/log/ptp4l.err.log
 

An example log file will look as shown below

QSG_ptp4l_err_log  

The output log of PHC2SYS can be verified by giving the following command

tail -f /var/log/phc2sys.log
 

An example log file will look as shown below

QSG_phc2sys_log  

The error log of PHC2SYS can be verified by giving the following command

tail -f /var/log/phc2sys.err.log
 

The command normally does not show any output, however in case of repeated lines as shown in the example log file below, it indicates that another time source is attempting to take control over the system’s time. In this case, you are probably running ntp, chrony, systemd-timesyncd.service or something similar in parallel. This must then be switched off to let PTP and PHC2SYS control the time.

QSG_phc2sys_err_log  

Test setup

 

Image below shows the test setup followed to run the PubSub application

QSG_test_setup  

You can follow either of the above listed network to run the application

 

Steps to run OPC UA PubSub application

 

Clone the open62541 stack with the following command

git clone https://github.com/open62541/open62541.git
 

Image attached below shows the overview of the target applications

  QSG_application_overview
 

Follow the steps given below to build the application

cd open62541/
 
git fetch origin pull/3363/head:XDP_PUBSUB && git checkout XDP_PUBSUB
 
mkdir build
 
cd build/
 
cmake -DUA_BUILD_EXAMPLES=ON -DUA_ENABLE_PUBSUB=ON -DUA_ENABLE_PUBSUB_CUSTOM_PUBLISH_HANDLING=ON -DUA_ENABLE_PUBSUB_ETH_UADP=ON -DUA_ENABLE_PUBSUB_ETH_UADP_XDP_RECV=ON ..
 

Note: Ensure the interface in which you prefer to run the application is set properly in the TSN_XDP_mps_loopback.c and TSN_XDP_mps_publisher.c file by changing the following #defines

#define PUBLISHING_VLAN_INTERFACE
 
#define SUBSCRIBING_INTERFACE
 

Optional Step: To view the data written in csv files, uncomment the following #define in TSN_XDP_mps_loopback.c and TSN_XDP_mps_publisher.c present in directory open62541/examples/pubsub_realtime/xdp/

#define UPDATE_MEASUREMENTS
 

Image attached below shows the overview of the .CSV log files generated by the applications

QSG_application_csv_log
 

TSN_XDP_mps_publisher generates publisher_T1.csv, subscriber_T8.csv log files and
TSN_XDP_mps_loopback generates publisher_T5.csv, subscriber_T4.csv log files respectively

 

Build the application by giving the following command in open62541/build directory

make -j3
 

Running OPC UA Pub/Sub application

 

Note: It is always recommended to run TSN_XDP_mps_loopback application first to avoid missing the initial data published by TSN_XDP_mps_publisher.

Run the Loopback application in Node 2 by entering the following command

sudo ./bin/examples/TSN_XDP_mps_loopback
 

Run the Publisher application in Node 1 by entering the following command

sudo ./bin/examples/TSN_XDP_mps_publisher
 

Note: The CSV files will be generated in the build directory containing the timestamp and counter values for benchmarking only after terminating both the applications using “Ctrl + C”