<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki-ext.aps.anl.gov/blc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tguruswamy</id>
	<title>Beam Line Controls - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-ext.aps.anl.gov/blc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tguruswamy"/>
	<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Special:Contributions/Tguruswamy"/>
	<updated>2026-09-08T15:31:23Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=812</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=812"/>
		<updated>2025-04-14T18:29:31Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel(TLS) for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
Scistream's API TLS certificates are on the test servers at &amp;lt;code&amp;gt;/local/scistream&amp;lt;/code&amp;gt;. Use the folder corresponding to the server -- i.e. on server1, always use /server1; on server2, use /server2.&lt;br /&gt;
&lt;br /&gt;
== How data flows through the tunnel ==&lt;br /&gt;
&lt;br /&gt;
The tunnel consists of parts that work together:&lt;br /&gt;
&lt;br /&gt;
'''Server side (Inbound Request):''' Destination that receives data. TCP server listens for connections.&lt;br /&gt;
'''Client side (Outbound Request):''' Source that sends data. TCP client that actively creates new connections&lt;br /&gt;
&lt;br /&gt;
** Your client application connects to the local port (5100) on the client machine&lt;br /&gt;
** The SciStream outbound request forwards this connection through the secure tunnel&lt;br /&gt;
** The SciStream inbound request receives the forwarded connection&lt;br /&gt;
** Data is delivered to your server application listening on the receiver port (5300)&lt;br /&gt;
&lt;br /&gt;
== Request Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
'''Purpose:''' Sets up the receiving end of the tunnel. This establishes a listener on the specified SciStream endpoint that waits for incoming connections from the outbound request (other SciStream endpoint) and it forwards this connection to the &amp;lt;remote_ip&amp;gt;:&amp;lt;receiver_ports&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Sets up the sending end of the tunnel. This establishes a listener on the specified SciStream endpoint that waits for incoming connections from the client application and forwards that data to the other SciStream endpoint. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to (i.e. client should connect to {s2cs_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=811</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=811"/>
		<updated>2025-04-14T18:29:20Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel(TLS) for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
Scistream's API TLS certificates are on the test servers at &amp;lt;code&amp;gt;/local/scistream&amp;lt;/code&amp;gt;. Use the folder corresponding to the server -- i.e. on server1, always use /server1; on server2, use /server2.&lt;br /&gt;
&lt;br /&gt;
== How data flows through the tunnel ==&lt;br /&gt;
&lt;br /&gt;
The tunnel consists of parts that work together:&lt;br /&gt;
&lt;br /&gt;
'''Server side (Inbound Request):''' Destination that receives data. TCP server listens for connections.&lt;br /&gt;
'''Client side (Outbound Request):''' Source that sends data. TCP client that actively creates new connections&lt;br /&gt;
&lt;br /&gt;
** Your client application connects to the local port (5100) on the client machine&lt;br /&gt;
** The SciStream outbound request forwards this connection through the secure tunnel&lt;br /&gt;
** The SciStream inbound request receives the forwarded connection&lt;br /&gt;
** Data is delivered to your server application listening on the receiver port (5300)&lt;br /&gt;
&lt;br /&gt;
== Request Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
'''Purpose:''' Sets up the receiving end of the tunnel. This establishes a listener on the specified SciStream endpoint that waits for incoming connections from the outbound request (other SciStream endpoint) and it forwards this connection to the &amp;lt;remote_ip&amp;gt;:&amp;lt;receiver_ports&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Sets up the sending end of the tunnel. This establishes a listener on the local SciStream endpoint that waits for incoming connections from the client application and forwards that data to the other SciStream endpoint. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to (i.e. client should connect to {s2cs_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=810</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=810"/>
		<updated>2025-04-14T18:28:57Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel(TLS) for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
Scistream's API TLS certificates are on the test servers at &amp;lt;code&amp;gt;/local/scistream&amp;lt;/code&amp;gt;. Use the folder corresponding to the server -- i.e. on server1, always use /server1; on server2, use /server2.&lt;br /&gt;
&lt;br /&gt;
== How data flows through the tunnel ==&lt;br /&gt;
&lt;br /&gt;
The tunnel consists of parts that work together:&lt;br /&gt;
&lt;br /&gt;
'''Server side (Inbound Request):''' Destination that receives data. TCP server listens for connections.&lt;br /&gt;
'''Client side (Outbound Request):''' Source that sends data. TCP client that actively creates new connections&lt;br /&gt;
&lt;br /&gt;
** Your client application connects to the local port (5100) on the client machine&lt;br /&gt;
** The SciStream outbound request forwards this connection through the secure tunnel&lt;br /&gt;
** The SciStream inbound request receives the forwarded connection&lt;br /&gt;
** Data is delivered to your server application listening on the receiver port (5300)&lt;br /&gt;
&lt;br /&gt;
== Request Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
'''Purpose:''' Sets up the receiving end of the tunnel. This establishes a listener that waits for incoming connections from the outbound request (other SciStream endpoint) and it forwards this connection to the &amp;lt;remote_ip&amp;gt;:&amp;lt;receiver_ports&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Sets up the sending end of the tunnel. This establishes a listener on the local SciStream endpoint that waits for incoming connections from the client application and forwards that data to the other SciStream endpoint. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to (i.e. client should connect to {s2cs_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=809</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=809"/>
		<updated>2025-04-14T18:28:33Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel(TLS) for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
Scistream's API TLS certificates are on the test servers at &amp;lt;code&amp;gt;/local/scistream&amp;lt;/code&amp;gt;. Use the folder corresponding to the server -- i.e. on server1, always use /server1; on server2, use /server2.&lt;br /&gt;
&lt;br /&gt;
== How data flows through the tunnel ==&lt;br /&gt;
&lt;br /&gt;
The tunnel consists of parts that work together:&lt;br /&gt;
&lt;br /&gt;
'''Server side (Inbound Request):''' Destination that receives data. TCP server listens for connections.&lt;br /&gt;
'''Client side (Outbound Request):''' Source that sends data. TCP client that actively creates new connections&lt;br /&gt;
&lt;br /&gt;
** Your client application connects to the local port (5100) on the client machine&lt;br /&gt;
** The SciStream outbound request forwards this connection through the secure tunnel&lt;br /&gt;
** The SciStream inbound request receives the forwarded connection&lt;br /&gt;
** Data is delivered to your server application listening on the receiver port (5300)&lt;br /&gt;
&lt;br /&gt;
== Request Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
'''Purpose:''' Sets up the receiving end of the tunnel. This establishes a listener that waits for incoming connections from the outbound request and it forwards this connection to the &amp;lt;remote_ip&amp;gt;:&amp;lt;receiver_ports&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Sets up the sending end of the tunnel. This establishes a listener on the local SciStream endpoint that waits for incoming connections from the client application and forwards that data to the other SciStream endpoint. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to (i.e. client should connect to {s2cs_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=805</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=805"/>
		<updated>2025-04-14T15:22:26Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* SciStream Tunnel Setup Guide */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
Scistream TLS certificates are on the test servers at &amp;lt;code&amp;gt;/local/scistream&amp;lt;/code&amp;gt;. Use the folder corresponding to the server -- i.e. on server1, always use /server1; on server2, use /server2.&lt;br /&gt;
&lt;br /&gt;
== Request Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=804</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=804"/>
		<updated>2025-04-14T15:21:59Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: remove server names&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
Scistream test server certificates are on the test servers at &amp;lt;code&amp;gt;/local/scistream&amp;lt;/code&amp;gt;. Use the folder corresponding to the server -- i.e. on server1, always use /server1; on server2, use /server2.&lt;br /&gt;
&lt;br /&gt;
== Request Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=803</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=803"/>
		<updated>2025-04-09T19:22:09Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: add cert location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
Scistream test server certificates are on updraft1/2 at &amp;lt;code&amp;gt;/local/scistream&amp;lt;/code&amp;gt;. Use the folder corresponding to the server -- i.e. on updraft1, always use /server1; on updraft2, use /server2.&lt;br /&gt;
&lt;br /&gt;
== Request Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=802</id>
		<title>SciStream at APS</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=SciStream_at_APS&amp;diff=802"/>
		<updated>2025-04-09T19:17:45Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: from talks with flavio&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SciStream Tunnel Setup Guide =&lt;br /&gt;
&lt;br /&gt;
This guide provides step-by-step instructions on how to tunnel a connection through SciStream using &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt; running from a container. This setup involves two endpoints, each running on separate hosts, to establish a secure tunnel for forwarding packets.&lt;br /&gt;
&lt;br /&gt;
== Endpoint Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Inbound Request (&amp;quot;Server side&amp;quot;: 192.168.150.1) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server1:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 inbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.1:5000 --receiver_ports 5300 --num_conn 1 --server_cert=/scistream/server.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The address the user application is listening on.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: The port the user application is listening on (i.e. the user application is bound to {remote_ip:receiver_port}).&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
&lt;br /&gt;
'''Note the UID:'''&lt;br /&gt;
&lt;br /&gt;
After running the command, note the UID and listener port provided in the output. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5000 INVALID_TOKEN PROD&lt;br /&gt;
sending client request message&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
sending for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.1:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Outbound Request (&amp;quot;Client side&amp;quot;: 192.168.150.2) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;podman run --rm --net=host -v ./server2:/scistream --entrypoint=s2uc castroflaviojr/scistream:1.2.1 outbound-request --remote_ip 192.168.150.1 --s2cs 192.168.150.2:5000 --receiver_ports 5100 --num_conn 1 --server_cert=/scistream/server.crt bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.1:5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Parameters:'''&lt;br /&gt;
** &amp;lt;code&amp;gt;--remote_ip&amp;lt;/code&amp;gt;: The eventual destination IP address we want data to be forwarded to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--s2cs&amp;lt;/code&amp;gt;: The IP and port for the local s2cs scistream control server.&lt;br /&gt;
** &amp;lt;code&amp;gt;--receiver_ports&amp;lt;/code&amp;gt;: Local port which the client application will connect to.&lt;br /&gt;
** &amp;lt;code&amp;gt;--num_conn&amp;lt;/code&amp;gt;: Number of connections to establish.&lt;br /&gt;
** &amp;lt;code&amp;gt;--server_cert&amp;lt;/code&amp;gt;: Path to the server certificate for TLS.&lt;br /&gt;
** &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt;: Use the UID noted from the inbound request.&lt;br /&gt;
** &amp;lt;code&amp;gt;IP:PORT&amp;lt;/code&amp;gt;: Use the IP and port noted from the inbound request.&lt;br /&gt;
&lt;br /&gt;
Example output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uid; s2cs; access_token; role&lt;br /&gt;
bd9f1a7e-04d7-11f0-b44c-946dae415862 192.168.150.2:5000 INVALID_TOKEN CONS&lt;br /&gt;
started client request&lt;br /&gt;
waiting for hello message&lt;br /&gt;
Hello message sent successfully&lt;br /&gt;
Listeners: ['192.168.150.2:5100']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
* '''Check Listening Ports:'''&lt;br /&gt;
&lt;br /&gt;
On both hosts, verify that the &amp;lt;code&amp;gt;stunnel&amp;lt;/code&amp;gt; processes are listening on the expected ports using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ss -tlpn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Test the Tunnel:'''&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; to test the tunnel:&lt;br /&gt;
&lt;br /&gt;
* '''Client Side (Host 192.168.150.2):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -c 192.168.150.2 -p 5100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Server Side (Host 192.168.150.1):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iperf3 -s -p 5300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing the Connection ==&lt;br /&gt;
&lt;br /&gt;
To close a connection request, use the &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; option with &amp;lt;code&amp;gt;s2uc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;s2uc release &amp;lt;uid&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=760</id>
		<title>EPICS networking</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=760"/>
		<updated>2024-02-27T17:42:03Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Multiple paths between client and server */ adjust note about pva localhost broadcast&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EPICS networking =&lt;br /&gt;
&lt;br /&gt;
For basic terminology, see [[EPICS 101]].&lt;br /&gt;
&lt;br /&gt;
An EPICS IOC is an application which serves EPICS clients (command-line programs like caget; applications using p4p, pyepics, pvapy, or other libraries; GUI display managers like MEDM or caQtDM) process variables over the network. They do so using either the Channel Access (CA) or PVAccess (PVA) network protocols.&lt;br /&gt;
&lt;br /&gt;
By default, an EPICS IOC with CA and/or PVA support enabled will listen for clients on '''all available network interfaces​.'''&lt;br /&gt;
&lt;br /&gt;
== Connection Flow ==&lt;br /&gt;
&lt;br /&gt;
* A client emits a request for particular PV names, e.g. ''13SIM1:cam1:Image​'' to a specific &amp;quot;search list&amp;quot; of IP addresses (which may be unicast or broadcast addresses).&lt;br /&gt;
* Any IOC which receives the request and provides any PV name requested will respond to the client​.&lt;br /&gt;
* The client and Server now know each other's IP addresses​.&lt;br /&gt;
* A one-to-one communications channel between client and server is established​.&lt;br /&gt;
* The opened Channel is used for either a one-off READ or WRITE, or a SUBSCRIPTION (monitor) to receive an update every time the PV value changes​.&lt;br /&gt;
&lt;br /&gt;
This flow is more or less the same for the CA or PVA protocols​, and involves a mix of TCP/IP and UDP/IP transport with varying port numbers. Many client libraries (e.g. pyepics) will cache connections, or convert repeated READs into SUBSCRIPTIONS behind-the-scenes to save resources.&lt;br /&gt;
&lt;br /&gt;
This system ensures that a newly-started IOC is immediately accessible to all clients without needing to register with a central server, and the only information you need to connect to a PV is its full name.&lt;br /&gt;
&lt;br /&gt;
== The search request ==&lt;br /&gt;
&lt;br /&gt;
EPICS clients follow a simple two-step process to construct the destination of a PV search request. This is performed separately for CA and PVA protocols (substitute ''either'' &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PVA&amp;lt;/code&amp;gt; into the names of the environment variables described below).&lt;br /&gt;
&lt;br /&gt;
# Start with an empty list.&lt;br /&gt;
# If the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=yes&amp;lt;/code&amp;gt;, then add all broadcast IP addresses for all available network interfaces to the list.&lt;br /&gt;
#* &amp;quot;yes&amp;quot; is the default value if unset.&lt;br /&gt;
#* If &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt;, skip this step.&lt;br /&gt;
# Add the contents of the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the list.&lt;br /&gt;
#* This should be a space-separated list of IP addresses or hostnames.&lt;br /&gt;
# Send the PV search request to every IP or host in the list.&lt;br /&gt;
&lt;br /&gt;
Environment variables should be set prior to starting the client program to be effective, and may need to be &amp;quot;exported&amp;quot; to persist (depending on your shell). Example in bash:&lt;br /&gt;
&lt;br /&gt;
    export EPICS_CA_AUTO_ADDR_LIST=no EPICS_CA_ADDR_LIST=s1pvgate.xray.aps.anl.gov&lt;br /&gt;
    caget 1BM:ExampleVariable&lt;br /&gt;
&lt;br /&gt;
== Potential issues ==&lt;br /&gt;
=== Crossing subnet boundaries ===&lt;br /&gt;
&lt;br /&gt;
Since by default only broadcast addresses are in the search request destination list, and broadcast packets are not routed between subnets, without extra configuration you will only be able to find PVs on the same subnet as your client.&lt;br /&gt;
&lt;br /&gt;
;Solution 1&amp;amp;#58; add the IP address of the IOC server directly to &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt;.&lt;br /&gt;
:This works across subnet boundaries as long as the required ports are available (no firewalls), but doesn't scale well if there are many IOCs you want to connect to.&lt;br /&gt;
&lt;br /&gt;
;Solution 2&amp;amp;#58; set up a PV Gateway server in the IOC subnet, and add the PV gateway IP address&lt;br /&gt;
:A [https://github.com/epics-extensions/ca-gateway PV gateway] is a dedicated server program which relays incoming requests on to the rest of the subnet. It can also apply security rules to the traffic it is forwarding, e.g. it can force a PV to be read-only. The PV gateway hostname or IP address must be added to the relevant &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
; Solution 3&amp;amp;#58; set up a PV nameserver.&lt;br /&gt;
:Similar to DNS, the [https://github.com/epics-extensions/ca-nameserver nameserver] is a server program that takes over responding to all client name search requests. In this setup, the nameserver must be added to the &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
=== Multiple paths between client and server ===&lt;br /&gt;
&lt;br /&gt;
An IOC will reply to '''all''' requests for PVs it servers, even multiple ones from the same client.&lt;br /&gt;
&lt;br /&gt;
Therefore if there are multiple network paths from client to server, for example because the client and/or server have multiple network interfaces, the server may see multiple requests from the client and the client will get multiple responses, each with a different IP.&lt;br /&gt;
&lt;br /&gt;
The same situation can occur if multiple IOCs are serving a PV with the exact same name. The client will usually pick the first response it receives and print a warning to the user, for example:&lt;br /&gt;
&lt;br /&gt;
    12-12-2023 01:36:01 Channel Access Exception Channel: &amp;quot;bdpSim0:cam1:Model_RBV&amp;quot;, Connecting to: beryl-gpm.xray.aps.anl.gov:5064, Ignored: 10.0.0.1:5064 on ? (op=5 data_type=DBR_invalid count=0) &lt;br /&gt;
&lt;br /&gt;
Which server IP is selected is essentially random each time a search request completes and a connection is created, and there is no guarantee it is the optimal or fastest path from client to server.&lt;br /&gt;
&lt;br /&gt;
;Solution&amp;amp;#58; limit EPICS traffic to only one interface and one network path.&lt;br /&gt;
:On the client, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt; and manually set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the single broadcast address on the network interface you want to use.&lt;br /&gt;
&lt;br /&gt;
It is also possible to set &amp;lt;code&amp;gt;EPICS_{CA,PVA}S_INTF_ADDR_LIST&amp;lt;/code&amp;gt; on the server to limit the addresses the IOC listens on, but this must be done ''before'' starting the IOC.&lt;br /&gt;
&lt;br /&gt;
The most common variant of this situation is when the client and server are on the same computer. In this case, all the available network interfaces (including the loopback interface ''lo'') present a valid path from client to server.&lt;br /&gt;
&lt;br /&gt;
To limit all traffic to only travel over the loopback interface (which will be the fastest), before running your client set:&lt;br /&gt;
&lt;br /&gt;
   EPICS_CA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_PVA_ADDR_LIST=127.0.0.1​&lt;br /&gt;
   EPICS_CA_AUTO_ADDR_LIST=no​&lt;br /&gt;
   EPICS_PVA_AUTO_ADDR_LIST=no&lt;br /&gt;
&lt;br /&gt;
The difference between using only the loopback address (127.0.0.1) and using the loopback broadcast address (127.255.255.255) is that the broadcast address supports communicating with multiple IOCs on the same host on Linux. See the [https://docs.epics-controls.org/en/latest/sys-admin/channel-access-reach-multiple-soft-iocs-linux.html EPICS documentation] for more details and alternative solutions.&lt;br /&gt;
&lt;br /&gt;
Note: PVA is different to CA in this example because using the broadcast address 127.255.255.255 does not work for the EPICSv7 built-in pvaServer due to an issue in the implementation. See TechTalk: [https://epics.anl.gov/tech-talk/2021/msg00806.php] [https://epics.anl.gov/tech-talk/2021/msg00807.php]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-14/12-docs/CAref.html EPICS Channel Access Reference Manual (v3.14)]&lt;br /&gt;
* [https://mdavidsaver.github.io/pvxs/netconfig.html PVXS (PVA) Network Configuration Information]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=759</id>
		<title>EPICS networking</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=759"/>
		<updated>2024-02-26T21:58:00Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Potential issues */ fix techtalk link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EPICS networking =&lt;br /&gt;
&lt;br /&gt;
For basic terminology, see [[EPICS 101]].&lt;br /&gt;
&lt;br /&gt;
An EPICS IOC is an application which serves EPICS clients (command-line programs like caget; applications using p4p, pyepics, pvapy, or other libraries; GUI display managers like MEDM or caQtDM) process variables over the network. They do so using either the Channel Access (CA) or PVAccess (PVA) network protocols.&lt;br /&gt;
&lt;br /&gt;
By default, an EPICS IOC with CA and/or PVA support enabled will listen for clients on '''all available network interfaces​.'''&lt;br /&gt;
&lt;br /&gt;
== Connection Flow ==&lt;br /&gt;
&lt;br /&gt;
* A client emits a request for particular PV names, e.g. ''13SIM1:cam1:Image​'' to a specific &amp;quot;search list&amp;quot; of IP addresses (which may be unicast or broadcast addresses).&lt;br /&gt;
* Any IOC which receives the request and provides any PV name requested will respond to the client​.&lt;br /&gt;
* The client and Server now know each other's IP addresses​.&lt;br /&gt;
* A one-to-one communications channel between client and server is established​.&lt;br /&gt;
* The opened Channel is used for either a one-off READ or WRITE, or a SUBSCRIPTION (monitor) to receive an update every time the PV value changes​.&lt;br /&gt;
&lt;br /&gt;
This flow is more or less the same for the CA or PVA protocols​, and involves a mix of TCP/IP and UDP/IP transport with varying port numbers. Many client libraries (e.g. pyepics) will cache connections, or convert repeated READs into SUBSCRIPTIONS behind-the-scenes to save resources.&lt;br /&gt;
&lt;br /&gt;
This system ensures that a newly-started IOC is immediately accessible to all clients without needing to register with a central server, and the only information you need to connect to a PV is its full name.&lt;br /&gt;
&lt;br /&gt;
== The search request ==&lt;br /&gt;
&lt;br /&gt;
EPICS clients follow a simple two-step process to construct the destination of a PV search request. This is performed separately for CA and PVA protocols (substitute ''either'' &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PVA&amp;lt;/code&amp;gt; into the names of the environment variables described below).&lt;br /&gt;
&lt;br /&gt;
# Start with an empty list.&lt;br /&gt;
# If the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=yes&amp;lt;/code&amp;gt;, then add all broadcast IP addresses for all available network interfaces to the list.&lt;br /&gt;
#* &amp;quot;yes&amp;quot; is the default value if unset.&lt;br /&gt;
#* If &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt;, skip this step.&lt;br /&gt;
# Add the contents of the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the list.&lt;br /&gt;
#* This should be a space-separated list of IP addresses or hostnames.&lt;br /&gt;
# Send the PV search request to every IP or host in the list.&lt;br /&gt;
&lt;br /&gt;
Environment variables should be set prior to starting the client program to be effective, and may need to be &amp;quot;exported&amp;quot; to persist (depending on your shell). Example in bash:&lt;br /&gt;
&lt;br /&gt;
    export EPICS_CA_AUTO_ADDR_LIST=no EPICS_CA_ADDR_LIST=s1pvgate.xray.aps.anl.gov&lt;br /&gt;
    caget 1BM:ExampleVariable&lt;br /&gt;
&lt;br /&gt;
== Potential issues ==&lt;br /&gt;
=== Crossing subnet boundaries ===&lt;br /&gt;
&lt;br /&gt;
Since by default only broadcast addresses are in the search request destination list, and broadcast packets are not routed between subnets, without extra configuration you will only be able to find PVs on the same subnet as your client.&lt;br /&gt;
&lt;br /&gt;
;Solution 1&amp;amp;#58; add the IP address of the IOC server directly to &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt;.&lt;br /&gt;
:This works across subnet boundaries as long as the required ports are available (no firewalls), but doesn't scale well if there are many IOCs you want to connect to.&lt;br /&gt;
&lt;br /&gt;
;Solution 2&amp;amp;#58; set up a PV Gateway server in the IOC subnet, and add the PV gateway IP address&lt;br /&gt;
:A [https://github.com/epics-extensions/ca-gateway PV gateway] is a dedicated server program which relays incoming requests on to the rest of the subnet. It can also apply security rules to the traffic it is forwarding, e.g. it can force a PV to be read-only. The PV gateway hostname or IP address must be added to the relevant &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
; Solution 3&amp;amp;#58; set up a PV nameserver.&lt;br /&gt;
:Similar to DNS, the [https://github.com/epics-extensions/ca-nameserver nameserver] is a server program that takes over responding to all client name search requests. In this setup, the nameserver must be added to the &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
=== Multiple paths between client and server ===&lt;br /&gt;
&lt;br /&gt;
An IOC will reply to '''all''' requests for PVs it servers, even multiple ones from the same client.&lt;br /&gt;
&lt;br /&gt;
Therefore if there are multiple network paths from client to server, for example because the client and/or server have multiple network interfaces, the server may see multiple requests from the client and the client will get multiple responses, each with a different IP.&lt;br /&gt;
&lt;br /&gt;
The same situation can occur if multiple IOCs are serving a PV with the exact same name. The client will usually pick the first response it receives and print a warning to the user, for example:&lt;br /&gt;
&lt;br /&gt;
    12-12-2023 01:36:01 Channel Access Exception Channel: &amp;quot;bdpSim0:cam1:Model_RBV&amp;quot;, Connecting to: beryl-gpm.xray.aps.anl.gov:5064, Ignored: 10.0.0.1:5064 on ? (op=5 data_type=DBR_invalid count=0) &lt;br /&gt;
&lt;br /&gt;
Which server IP is selected is essentially random each time a search request completes and a connection is created, and there is no guarantee it is the optimal or fastest path from client to server.&lt;br /&gt;
&lt;br /&gt;
;Solution&amp;amp;#58; limit EPICS traffic to only one interface and one network path.&lt;br /&gt;
:On the client, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt; and manually set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the single broadcast address on the network interface you want to use.&lt;br /&gt;
&lt;br /&gt;
It is also possible to set &amp;lt;code&amp;gt;EPICS_{CA,PVA}S_INTF_ADDR_LIST&amp;lt;/code&amp;gt; on the server to limit the addresses the IOC listens on, but this must be done ''before'' starting the IOC.&lt;br /&gt;
&lt;br /&gt;
The most common variant of this situation is when the client and server are on the same computer. In this case, all the available network interfaces (including the loopback interface ''lo'') present a valid path from client to server.&lt;br /&gt;
&lt;br /&gt;
To limit all traffic to only travel over the loopback interface (which will be the fastest), before running your client set:&lt;br /&gt;
&lt;br /&gt;
   EPICS_CA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_PVA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_CA_AUTO_ADDR_LIST=no​&lt;br /&gt;
   EPICS_PVA_AUTO_ADDR_LIST=no&lt;br /&gt;
&lt;br /&gt;
The difference between using only the loopback address (127.0.0.1) and using the loopback broadcast address (127.255.255.255) is that the broadcast address supports communicating with multiple IOCs on the same host on Linux. See the [https://docs.epics-controls.org/en/latest/sys-admin/channel-access-reach-multiple-soft-iocs-linux.html EPICS documentation] for more details and alternative solutions.&lt;br /&gt;
&lt;br /&gt;
Note: Limiting traffic to 127.0.0.1/127.255.255.255 may not work for the EPICSv7 built-in pvaServer due to an issue in the implementation, in which case try a different local IP. See TechTalk: [https://epics.anl.gov/tech-talk/2021/msg00806.php] [https://epics.anl.gov/tech-talk/2021/msg00807.php]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-14/12-docs/CAref.html EPICS Channel Access Reference Manual (v3.14)]&lt;br /&gt;
* [https://mdavidsaver.github.io/pvxs/netconfig.html PVXS (PVA) Network Configuration Information]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=758</id>
		<title>EPICS networking</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=758"/>
		<updated>2024-02-21T21:47:49Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* The search request */ reword&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EPICS networking =&lt;br /&gt;
&lt;br /&gt;
For basic terminology, see [[EPICS 101]].&lt;br /&gt;
&lt;br /&gt;
An EPICS IOC is an application which serves EPICS clients (command-line programs like caget; applications using p4p, pyepics, pvapy, or other libraries; GUI display managers like MEDM or caQtDM) process variables over the network. They do so using either the Channel Access (CA) or PVAccess (PVA) network protocols.&lt;br /&gt;
&lt;br /&gt;
By default, an EPICS IOC with CA and/or PVA support enabled will listen for clients on '''all available network interfaces​.'''&lt;br /&gt;
&lt;br /&gt;
== Connection Flow ==&lt;br /&gt;
&lt;br /&gt;
* A client emits a request for particular PV names, e.g. ''13SIM1:cam1:Image​'' to a specific &amp;quot;search list&amp;quot; of IP addresses (which may be unicast or broadcast addresses).&lt;br /&gt;
* Any IOC which receives the request and provides any PV name requested will respond to the client​.&lt;br /&gt;
* The client and Server now know each other's IP addresses​.&lt;br /&gt;
* A one-to-one communications channel between client and server is established​.&lt;br /&gt;
* The opened Channel is used for either a one-off READ or WRITE, or a SUBSCRIPTION (monitor) to receive an update every time the PV value changes​.&lt;br /&gt;
&lt;br /&gt;
This flow is more or less the same for the CA or PVA protocols​, and involves a mix of TCP/IP and UDP/IP transport with varying port numbers. Many client libraries (e.g. pyepics) will cache connections, or convert repeated READs into SUBSCRIPTIONS behind-the-scenes to save resources.&lt;br /&gt;
&lt;br /&gt;
This system ensures that a newly-started IOC is immediately accessible to all clients without needing to register with a central server, and the only information you need to connect to a PV is its full name.&lt;br /&gt;
&lt;br /&gt;
== The search request ==&lt;br /&gt;
&lt;br /&gt;
EPICS clients follow a simple two-step process to construct the destination of a PV search request. This is performed separately for CA and PVA protocols (substitute ''either'' &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PVA&amp;lt;/code&amp;gt; into the names of the environment variables described below).&lt;br /&gt;
&lt;br /&gt;
# Start with an empty list.&lt;br /&gt;
# If the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=yes&amp;lt;/code&amp;gt;, then add all broadcast IP addresses for all available network interfaces to the list.&lt;br /&gt;
#* &amp;quot;yes&amp;quot; is the default value if unset.&lt;br /&gt;
#* If &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt;, skip this step.&lt;br /&gt;
# Add the contents of the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the list.&lt;br /&gt;
#* This should be a space-separated list of IP addresses or hostnames.&lt;br /&gt;
# Send the PV search request to every IP or host in the list.&lt;br /&gt;
&lt;br /&gt;
Environment variables should be set prior to starting the client program to be effective, and may need to be &amp;quot;exported&amp;quot; to persist (depending on your shell). Example in bash:&lt;br /&gt;
&lt;br /&gt;
    export EPICS_CA_AUTO_ADDR_LIST=no EPICS_CA_ADDR_LIST=s1pvgate.xray.aps.anl.gov&lt;br /&gt;
    caget 1BM:ExampleVariable&lt;br /&gt;
&lt;br /&gt;
== Potential issues ==&lt;br /&gt;
=== Crossing subnet boundaries ===&lt;br /&gt;
&lt;br /&gt;
Since by default only broadcast addresses are in the search request destination list, and broadcast packets are not routed between subnets, without extra configuration you will only be able to find PVs on the same subnet as your client.&lt;br /&gt;
&lt;br /&gt;
;Solution 1&amp;amp;#58; add the IP address of the IOC server directly to &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt;.&lt;br /&gt;
:This works across subnet boundaries as long as the required ports are available (no firewalls), but doesn't scale well if there are many IOCs you want to connect to.&lt;br /&gt;
&lt;br /&gt;
;Solution 2&amp;amp;#58; set up a PV Gateway server in the IOC subnet, and add the PV gateway IP address&lt;br /&gt;
:A [https://github.com/epics-extensions/ca-gateway PV gateway] is a dedicated server program which relays incoming requests on to the rest of the subnet. It can also apply security rules to the traffic it is forwarding, e.g. it can force a PV to be read-only. The PV gateway hostname or IP address must be added to the relevant &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
; Solution 3&amp;amp;#58; set up a PV nameserver.&lt;br /&gt;
:Similar to DNS, the [https://github.com/epics-extensions/ca-nameserver nameserver] is a server program that takes over responding to all client name search requests. In this setup, the nameserver must be added to the &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
=== Multiple paths between client and server ===&lt;br /&gt;
&lt;br /&gt;
An IOC will reply to '''all''' requests for PVs it servers, even multiple ones from the same client.&lt;br /&gt;
&lt;br /&gt;
Therefore if there are multiple network paths from client to server, for example because the client and/or server have multiple network interfaces, the server may see multiple requests from the client and the client will get multiple responses, each with a different IP.&lt;br /&gt;
&lt;br /&gt;
The same situation can occur if multiple IOCs are serving a PV with the exact same name. The client will usually pick the first response it receives and print a warning to the user, for example:&lt;br /&gt;
&lt;br /&gt;
    12-12-2023 01:36:01 Channel Access Exception Channel: &amp;quot;bdpSim0:cam1:Model_RBV&amp;quot;, Connecting to: beryl-gpm.xray.aps.anl.gov:5064, Ignored: 10.0.0.1:5064 on ? (op=5 data_type=DBR_invalid count=0) &lt;br /&gt;
&lt;br /&gt;
Which server IP is selected is essentially random each time a search request completes and a connection is created, and there is no guarantee it is the optimal or fastest path from client to server.&lt;br /&gt;
&lt;br /&gt;
;Solution&amp;amp;#58; limit EPICS traffic to only one interface and one network path.&lt;br /&gt;
:On the client, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt; and manually set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the single broadcast address on the network interface you want to use.&lt;br /&gt;
&lt;br /&gt;
It is also possible to set &amp;lt;code&amp;gt;EPICS_{CA,PVA}S_INTF_ADDR_LIST&amp;lt;/code&amp;gt; on the server to limit the addresses the IOC listens on, but this must be done ''before'' starting the IOC.&lt;br /&gt;
&lt;br /&gt;
The most common variant of this situation is when the client and server are on the same computer. In this case, all the available network interfaces (including the loopback interface ''lo'') present a valid path from client to server.&lt;br /&gt;
&lt;br /&gt;
To limit all traffic to only travel over the loopback interface (which will be the fastest), before running your client set:&lt;br /&gt;
&lt;br /&gt;
   EPICS_CA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_PVA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_CA_AUTO_ADDR_LIST=no​&lt;br /&gt;
   EPICS_PVA_AUTO_ADDR_LIST=no&lt;br /&gt;
&lt;br /&gt;
The difference between using only the loopback address (127.0.0.1) and using the loopback broadcast address (127.255.255.255) is that the broadcast address supports communicating with multiple IOCs on the same host on Linux. See the [https://docs.epics-controls.org/en/latest/sys-admin/channel-access-reach-multiple-soft-iocs-linux.html EPICS documentation] for more details and alternative solutions.&lt;br /&gt;
&lt;br /&gt;
Note: Limiting traffic to 127.0.0.1/127.255.255.255 may not work for the EPICSv7 built-in pvaServer due to an issue in the implementation, in which case try a different local IP. See TechTalk: [https://epics.anl.gov/tech-talk/2021/msg00806.php] [https://epics.anl.gov/tech-talk/2021/msg00806.php]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-14/12-docs/CAref.html EPICS Channel Access Reference Manual (v3.14)]&lt;br /&gt;
* [https://mdavidsaver.github.io/pvxs/netconfig.html PVXS (PVA) Network Configuration Information]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=757</id>
		<title>EPICS networking</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=757"/>
		<updated>2024-02-21T21:37:12Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Connection Flow */ mention ip search list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EPICS networking =&lt;br /&gt;
&lt;br /&gt;
For basic terminology, see [[EPICS 101]].&lt;br /&gt;
&lt;br /&gt;
An EPICS IOC is an application which serves EPICS clients (command-line programs like caget; applications using p4p, pyepics, pvapy, or other libraries; GUI display managers like MEDM or caQtDM) process variables over the network. They do so using either the Channel Access (CA) or PVAccess (PVA) network protocols.&lt;br /&gt;
&lt;br /&gt;
By default, an EPICS IOC with CA and/or PVA support enabled will listen for clients on '''all available network interfaces​.'''&lt;br /&gt;
&lt;br /&gt;
== Connection Flow ==&lt;br /&gt;
&lt;br /&gt;
* A client emits a request for particular PV names, e.g. ''13SIM1:cam1:Image​'' to a specific &amp;quot;search list&amp;quot; of IP addresses (which may be unicast or broadcast addresses).&lt;br /&gt;
* Any IOC which receives the request and provides any PV name requested will respond to the client​.&lt;br /&gt;
* The client and Server now know each other's IP addresses​.&lt;br /&gt;
* A one-to-one communications channel between client and server is established​.&lt;br /&gt;
* The opened Channel is used for either a one-off READ or WRITE, or a SUBSCRIPTION (monitor) to receive an update every time the PV value changes​.&lt;br /&gt;
&lt;br /&gt;
This flow is more or less the same for the CA or PVA protocols​, and involves a mix of TCP/IP and UDP/IP transport with varying port numbers. Many client libraries (e.g. pyepics) will cache connections, or convert repeated READs into SUBSCRIPTIONS behind-the-scenes to save resources.&lt;br /&gt;
&lt;br /&gt;
This system ensures that a newly-started IOC is immediately accessible to all clients without needing to register with a central server, and the only information you need to connect to a PV is its full name.&lt;br /&gt;
&lt;br /&gt;
== The search request ==&lt;br /&gt;
&lt;br /&gt;
EPICS clients follow a simple two-step process to construct the destination of a PV search request. This is performed separately for CA and PVA protocols (substitute ''either'' &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PVA&amp;lt;/code&amp;gt; into the names of the environment variables described below).&lt;br /&gt;
&lt;br /&gt;
# Start with an empty list.&lt;br /&gt;
# If the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=yes&amp;lt;/code&amp;gt;, then add all broadcast IP addresses for all available network interfaces to the list.&lt;br /&gt;
#* &amp;quot;yes&amp;quot; is the default value if unset.&lt;br /&gt;
#* To skip this step, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Add the contents of the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the list.&lt;br /&gt;
#* This should be a space-separated list of IP addresses or hostnames.&lt;br /&gt;
# Send the PV search request to every IP or host in the list.&lt;br /&gt;
&lt;br /&gt;
Environment variables should be set prior to starting the client program to be effective, and may need to be &amp;quot;exported&amp;quot; to persist (depending on your shell). Example in bash:&lt;br /&gt;
&lt;br /&gt;
    export EPICS_CA_AUTO_ADDR_LIST=no EPICS_CA_ADDR_LIST=s1pvgate.xray.aps.anl.gov&lt;br /&gt;
    caget 1BM:ExampleVariable&lt;br /&gt;
&lt;br /&gt;
== Potential issues ==&lt;br /&gt;
=== Crossing subnet boundaries ===&lt;br /&gt;
&lt;br /&gt;
Since by default only broadcast addresses are in the search request destination list, and broadcast packets are not routed between subnets, without extra configuration you will only be able to find PVs on the same subnet as your client.&lt;br /&gt;
&lt;br /&gt;
;Solution 1&amp;amp;#58; add the IP address of the IOC server directly to &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt;.&lt;br /&gt;
:This works across subnet boundaries as long as the required ports are available (no firewalls), but doesn't scale well if there are many IOCs you want to connect to.&lt;br /&gt;
&lt;br /&gt;
;Solution 2&amp;amp;#58; set up a PV Gateway server in the IOC subnet, and add the PV gateway IP address&lt;br /&gt;
:A [https://github.com/epics-extensions/ca-gateway PV gateway] is a dedicated server program which relays incoming requests on to the rest of the subnet. It can also apply security rules to the traffic it is forwarding, e.g. it can force a PV to be read-only. The PV gateway hostname or IP address must be added to the relevant &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
; Solution 3&amp;amp;#58; set up a PV nameserver.&lt;br /&gt;
:Similar to DNS, the [https://github.com/epics-extensions/ca-nameserver nameserver] is a server program that takes over responding to all client name search requests. In this setup, the nameserver must be added to the &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
=== Multiple paths between client and server ===&lt;br /&gt;
&lt;br /&gt;
An IOC will reply to '''all''' requests for PVs it servers, even multiple ones from the same client.&lt;br /&gt;
&lt;br /&gt;
Therefore if there are multiple network paths from client to server, for example because the client and/or server have multiple network interfaces, the server may see multiple requests from the client and the client will get multiple responses, each with a different IP.&lt;br /&gt;
&lt;br /&gt;
The same situation can occur if multiple IOCs are serving a PV with the exact same name. The client will usually pick the first response it receives and print a warning to the user, for example:&lt;br /&gt;
&lt;br /&gt;
    12-12-2023 01:36:01 Channel Access Exception Channel: &amp;quot;bdpSim0:cam1:Model_RBV&amp;quot;, Connecting to: beryl-gpm.xray.aps.anl.gov:5064, Ignored: 10.0.0.1:5064 on ? (op=5 data_type=DBR_invalid count=0) &lt;br /&gt;
&lt;br /&gt;
Which server IP is selected is essentially random each time a search request completes and a connection is created, and there is no guarantee it is the optimal or fastest path from client to server.&lt;br /&gt;
&lt;br /&gt;
;Solution&amp;amp;#58; limit EPICS traffic to only one interface and one network path.&lt;br /&gt;
:On the client, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt; and manually set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the single broadcast address on the network interface you want to use.&lt;br /&gt;
&lt;br /&gt;
It is also possible to set &amp;lt;code&amp;gt;EPICS_{CA,PVA}S_INTF_ADDR_LIST&amp;lt;/code&amp;gt; on the server to limit the addresses the IOC listens on, but this must be done ''before'' starting the IOC.&lt;br /&gt;
&lt;br /&gt;
The most common variant of this situation is when the client and server are on the same computer. In this case, all the available network interfaces (including the loopback interface ''lo'') present a valid path from client to server.&lt;br /&gt;
&lt;br /&gt;
To limit all traffic to only travel over the loopback interface (which will be the fastest), before running your client set:&lt;br /&gt;
&lt;br /&gt;
   EPICS_CA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_PVA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_CA_AUTO_ADDR_LIST=no​&lt;br /&gt;
   EPICS_PVA_AUTO_ADDR_LIST=no&lt;br /&gt;
&lt;br /&gt;
The difference between using only the loopback address (127.0.0.1) and using the loopback broadcast address (127.255.255.255) is that the broadcast address supports communicating with multiple IOCs on the same host on Linux. See the [https://docs.epics-controls.org/en/latest/sys-admin/channel-access-reach-multiple-soft-iocs-linux.html EPICS documentation] for more details and alternative solutions.&lt;br /&gt;
&lt;br /&gt;
Note: Limiting traffic to 127.0.0.1/127.255.255.255 may not work for the EPICSv7 built-in pvaServer due to an issue in the implementation, in which case try a different local IP. See TechTalk: [https://epics.anl.gov/tech-talk/2021/msg00806.php] [https://epics.anl.gov/tech-talk/2021/msg00806.php]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-14/12-docs/CAref.html EPICS Channel Access Reference Manual (v3.14)]&lt;br /&gt;
* [https://mdavidsaver.github.io/pvxs/netconfig.html PVXS (PVA) Network Configuration Information]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=746</id>
		<title>EPICS networking</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=746"/>
		<updated>2024-01-09T23:38:42Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Potential issues */ add additional techtalk link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EPICS networking =&lt;br /&gt;
&lt;br /&gt;
For basic terminology, see [[EPICS 101]].&lt;br /&gt;
&lt;br /&gt;
An EPICS IOC is an application which serves EPICS clients (command-line programs like caget; applications using p4p, pyepics, pvapy, or other libraries; GUI display managers like MEDM or caQtDM) process variables over the network. They do so using either the Channel Access (CA) or PVAccess (PVA) network protocols.&lt;br /&gt;
&lt;br /&gt;
By default, an EPICS IOC with CA and/or PVA support enabled will listen for clients on '''all available network interfaces​.'''&lt;br /&gt;
&lt;br /&gt;
== Connection Flow ==&lt;br /&gt;
&lt;br /&gt;
* A client emits a request for particular PV names, e.g. ''13SIM1:cam1:Image​''.&lt;br /&gt;
* Any IOC which receives the request and provides any PV name requested will respond to the client​.&lt;br /&gt;
* The client and Server now know each other's IP addresses​.&lt;br /&gt;
* A one-to-one communications channel between client and server is established​.&lt;br /&gt;
* The opened Channel is used for either a one-off READ or WRITE, or a SUBSCRIPTION (monitor) to receive an update every time the PV value changes​.&lt;br /&gt;
&lt;br /&gt;
This flow is more or less the same for the CA or PVA protocols​, and involves a mix of TCP/IP and UDP/IP transport with varying port numbers. Many client libraries (e.g. pyepics) will cache connections, or convert repeated READs into SUBSCRIPTIONS behind-the-scenes to save resources.&lt;br /&gt;
&lt;br /&gt;
This system ensures that a newly-started IOC is immediately accessible to all clients without needing to register with a central server, and the only information you need to connect to a PV is its full name.&lt;br /&gt;
&lt;br /&gt;
== The search request ==&lt;br /&gt;
&lt;br /&gt;
EPICS clients follow a simple two-step process to construct the destination of a PV search request. This is performed separately for CA and PVA protocols (substitute ''either'' &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PVA&amp;lt;/code&amp;gt; into the names of the environment variables described below).&lt;br /&gt;
&lt;br /&gt;
# Start with an empty list.&lt;br /&gt;
# If the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=yes&amp;lt;/code&amp;gt;, then add all broadcast IP addresses for all available network interfaces to the list.&lt;br /&gt;
#* &amp;quot;yes&amp;quot; is the default value if unset.&lt;br /&gt;
#* To skip this step, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Add the contents of the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the list.&lt;br /&gt;
#* This should be a space-separated list of IP addresses or hostnames.&lt;br /&gt;
# Send the PV search request to every IP or host in the list.&lt;br /&gt;
&lt;br /&gt;
Environment variables should be set prior to starting the client program to be effective, and may need to be &amp;quot;exported&amp;quot; to persist (depending on your shell). Example in bash:&lt;br /&gt;
&lt;br /&gt;
    export EPICS_CA_AUTO_ADDR_LIST=no EPICS_CA_ADDR_LIST=s1pvgate.xray.aps.anl.gov&lt;br /&gt;
    caget 1BM:ExampleVariable&lt;br /&gt;
&lt;br /&gt;
== Potential issues ==&lt;br /&gt;
=== Crossing subnet boundaries ===&lt;br /&gt;
&lt;br /&gt;
Since by default only broadcast addresses are in the search request destination list, and broadcast packets are not routed between subnets, without extra configuration you will only be able to find PVs on the same subnet as your client.&lt;br /&gt;
&lt;br /&gt;
;Solution 1&amp;amp;#58; add the IP address of the IOC server directly to &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt;.&lt;br /&gt;
:This works across subnet boundaries as long as the required ports are available (no firewalls), but doesn't scale well if there are many IOCs you want to connect to.&lt;br /&gt;
&lt;br /&gt;
;Solution 2&amp;amp;#58; set up a PV Gateway server in the IOC subnet, and add the PV gateway IP address&lt;br /&gt;
:A [https://github.com/epics-extensions/ca-gateway PV gateway] is a dedicated server program which relays incoming requests on to the rest of the subnet. It can also apply security rules to the traffic it is forwarding, e.g. it can force a PV to be read-only. The PV gateway hostname or IP address must be added to the relevant &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
; Solution 3&amp;amp;#58; set up a PV nameserver.&lt;br /&gt;
:Similar to DNS, the [https://github.com/epics-extensions/ca-nameserver nameserver] is a server program that takes over responding to all client name search requests. In this setup, the nameserver must be added to the &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
=== Multiple paths between client and server ===&lt;br /&gt;
&lt;br /&gt;
An IOC will reply to '''all''' requests for PVs it servers, even multiple ones from the same client.&lt;br /&gt;
&lt;br /&gt;
Therefore if there are multiple network paths from client to server, for example because the client and/or server have multiple network interfaces, the server may see multiple requests from the client and the client will get multiple responses, each with a different IP.&lt;br /&gt;
&lt;br /&gt;
The same situation can occur if multiple IOCs are serving a PV with the exact same name. The client will usually pick the first response it receives and print a warning to the user, for example:&lt;br /&gt;
&lt;br /&gt;
    12-12-2023 01:36:01 Channel Access Exception Channel: &amp;quot;bdpSim0:cam1:Model_RBV&amp;quot;, Connecting to: beryl-gpm.xray.aps.anl.gov:5064, Ignored: 10.0.0.1:5064 on ? (op=5 data_type=DBR_invalid count=0) &lt;br /&gt;
&lt;br /&gt;
Which server IP is selected is essentially random each time a search request completes and a connection is created, and there is no guarantee it is the optimal or fastest path from client to server.&lt;br /&gt;
&lt;br /&gt;
;Solution&amp;amp;#58; limit EPICS traffic to only one interface and one network path.&lt;br /&gt;
:On the client, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt; and manually set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the single broadcast address on the network interface you want to use.&lt;br /&gt;
&lt;br /&gt;
It is also possible to set &amp;lt;code&amp;gt;EPICS_{CA,PVA}S_INTF_ADDR_LIST&amp;lt;/code&amp;gt; on the server to limit the addresses the IOC listens on, but this must be done ''before'' starting the IOC.&lt;br /&gt;
&lt;br /&gt;
The most common variant of this situation is when the client and server are on the same computer. In this case, all the available network interfaces (including the loopback interface ''lo'') present a valid path from client to server.&lt;br /&gt;
&lt;br /&gt;
To limit all traffic to only travel over the loopback interface (which will be the fastest), before running your client set:&lt;br /&gt;
&lt;br /&gt;
   EPICS_CA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_PVA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_CA_AUTO_ADDR_LIST=no​&lt;br /&gt;
   EPICS_PVA_AUTO_ADDR_LIST=no&lt;br /&gt;
&lt;br /&gt;
The difference between using only the loopback address (127.0.0.1) and using the loopback broadcast address (127.255.255.255) is that the broadcast address supports communicating with multiple IOCs on the same host on Linux. See the [https://docs.epics-controls.org/en/latest/sys-admin/channel-access-reach-multiple-soft-iocs-linux.html EPICS documentation] for more details and alternative solutions.&lt;br /&gt;
&lt;br /&gt;
Note: Limiting traffic to 127.0.0.1/127.255.255.255 may not work for the EPICSv7 built-in pvaServer due to an issue in the implementation, in which case try a different local IP. See TechTalk: [https://epics.anl.gov/tech-talk/2021/msg00806.php] [https://epics.anl.gov/tech-talk/2021/msg00806.php]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-14/12-docs/CAref.html EPICS Channel Access Reference Manual (v3.14)]&lt;br /&gt;
* [https://mdavidsaver.github.io/pvxs/netconfig.html PVXS (PVA) Network Configuration Information]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=745</id>
		<title>EPICS networking</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=745"/>
		<updated>2024-01-09T23:37:03Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Potential issues */ issue with pvaServer and localhost&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EPICS networking =&lt;br /&gt;
&lt;br /&gt;
For basic terminology, see [[EPICS 101]].&lt;br /&gt;
&lt;br /&gt;
An EPICS IOC is an application which serves EPICS clients (command-line programs like caget; applications using p4p, pyepics, pvapy, or other libraries; GUI display managers like MEDM or caQtDM) process variables over the network. They do so using either the Channel Access (CA) or PVAccess (PVA) network protocols.&lt;br /&gt;
&lt;br /&gt;
By default, an EPICS IOC with CA and/or PVA support enabled will listen for clients on '''all available network interfaces​.'''&lt;br /&gt;
&lt;br /&gt;
== Connection Flow ==&lt;br /&gt;
&lt;br /&gt;
* A client emits a request for particular PV names, e.g. ''13SIM1:cam1:Image​''.&lt;br /&gt;
* Any IOC which receives the request and provides any PV name requested will respond to the client​.&lt;br /&gt;
* The client and Server now know each other's IP addresses​.&lt;br /&gt;
* A one-to-one communications channel between client and server is established​.&lt;br /&gt;
* The opened Channel is used for either a one-off READ or WRITE, or a SUBSCRIPTION (monitor) to receive an update every time the PV value changes​.&lt;br /&gt;
&lt;br /&gt;
This flow is more or less the same for the CA or PVA protocols​, and involves a mix of TCP/IP and UDP/IP transport with varying port numbers. Many client libraries (e.g. pyepics) will cache connections, or convert repeated READs into SUBSCRIPTIONS behind-the-scenes to save resources.&lt;br /&gt;
&lt;br /&gt;
This system ensures that a newly-started IOC is immediately accessible to all clients without needing to register with a central server, and the only information you need to connect to a PV is its full name.&lt;br /&gt;
&lt;br /&gt;
== The search request ==&lt;br /&gt;
&lt;br /&gt;
EPICS clients follow a simple two-step process to construct the destination of a PV search request. This is performed separately for CA and PVA protocols (substitute ''either'' &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PVA&amp;lt;/code&amp;gt; into the names of the environment variables described below).&lt;br /&gt;
&lt;br /&gt;
# Start with an empty list.&lt;br /&gt;
# If the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=yes&amp;lt;/code&amp;gt;, then add all broadcast IP addresses for all available network interfaces to the list.&lt;br /&gt;
#* &amp;quot;yes&amp;quot; is the default value if unset.&lt;br /&gt;
#* To skip this step, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Add the contents of the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the list.&lt;br /&gt;
#* This should be a space-separated list of IP addresses or hostnames.&lt;br /&gt;
# Send the PV search request to every IP or host in the list.&lt;br /&gt;
&lt;br /&gt;
Environment variables should be set prior to starting the client program to be effective, and may need to be &amp;quot;exported&amp;quot; to persist (depending on your shell). Example in bash:&lt;br /&gt;
&lt;br /&gt;
    export EPICS_CA_AUTO_ADDR_LIST=no EPICS_CA_ADDR_LIST=s1pvgate.xray.aps.anl.gov&lt;br /&gt;
    caget 1BM:ExampleVariable&lt;br /&gt;
&lt;br /&gt;
== Potential issues ==&lt;br /&gt;
=== Crossing subnet boundaries ===&lt;br /&gt;
&lt;br /&gt;
Since by default only broadcast addresses are in the search request destination list, and broadcast packets are not routed between subnets, without extra configuration you will only be able to find PVs on the same subnet as your client.&lt;br /&gt;
&lt;br /&gt;
;Solution 1&amp;amp;#58; add the IP address of the IOC server directly to &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt;.&lt;br /&gt;
:This works across subnet boundaries as long as the required ports are available (no firewalls), but doesn't scale well if there are many IOCs you want to connect to.&lt;br /&gt;
&lt;br /&gt;
;Solution 2&amp;amp;#58; set up a PV Gateway server in the IOC subnet, and add the PV gateway IP address&lt;br /&gt;
:A [https://github.com/epics-extensions/ca-gateway PV gateway] is a dedicated server program which relays incoming requests on to the rest of the subnet. It can also apply security rules to the traffic it is forwarding, e.g. it can force a PV to be read-only. The PV gateway hostname or IP address must be added to the relevant &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
; Solution 3&amp;amp;#58; set up a PV nameserver.&lt;br /&gt;
:Similar to DNS, the [https://github.com/epics-extensions/ca-nameserver nameserver] is a server program that takes over responding to all client name search requests. In this setup, the nameserver must be added to the &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
=== Multiple paths between client and server ===&lt;br /&gt;
&lt;br /&gt;
An IOC will reply to '''all''' requests for PVs it servers, even multiple ones from the same client.&lt;br /&gt;
&lt;br /&gt;
Therefore if there are multiple network paths from client to server, for example because the client and/or server have multiple network interfaces, the server may see multiple requests from the client and the client will get multiple responses, each with a different IP.&lt;br /&gt;
&lt;br /&gt;
The same situation can occur if multiple IOCs are serving a PV with the exact same name. The client will usually pick the first response it receives and print a warning to the user, for example:&lt;br /&gt;
&lt;br /&gt;
    12-12-2023 01:36:01 Channel Access Exception Channel: &amp;quot;bdpSim0:cam1:Model_RBV&amp;quot;, Connecting to: beryl-gpm.xray.aps.anl.gov:5064, Ignored: 10.0.0.1:5064 on ? (op=5 data_type=DBR_invalid count=0) &lt;br /&gt;
&lt;br /&gt;
Which server IP is selected is essentially random each time a search request completes and a connection is created, and there is no guarantee it is the optimal or fastest path from client to server.&lt;br /&gt;
&lt;br /&gt;
;Solution&amp;amp;#58; limit EPICS traffic to only one interface and one network path.&lt;br /&gt;
:On the client, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt; and manually set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the single broadcast address on the network interface you want to use.&lt;br /&gt;
&lt;br /&gt;
It is also possible to set &amp;lt;code&amp;gt;EPICS_{CA,PVA}S_INTF_ADDR_LIST&amp;lt;/code&amp;gt; on the server to limit the addresses the IOC listens on, but this must be done ''before'' starting the IOC.&lt;br /&gt;
&lt;br /&gt;
The most common variant of this situation is when the client and server are on the same computer. In this case, all the available network interfaces (including the loopback interface ''lo'') present a valid path from client to server.&lt;br /&gt;
&lt;br /&gt;
To limit all traffic to only travel over the loopback interface (which will be the fastest), before running your client set:&lt;br /&gt;
&lt;br /&gt;
   EPICS_CA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_PVA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_CA_AUTO_ADDR_LIST=no​&lt;br /&gt;
   EPICS_PVA_AUTO_ADDR_LIST=no&lt;br /&gt;
&lt;br /&gt;
The difference between using only the loopback address (127.0.0.1) and using the loopback broadcast address (127.255.255.255) is that the broadcast address supports communicating with multiple IOCs on the same host on Linux. See the [https://docs.epics-controls.org/en/latest/sys-admin/channel-access-reach-multiple-soft-iocs-linux.html EPICS documentation] for more details and alternative solutions.&lt;br /&gt;
&lt;br /&gt;
Note: Limiting traffic to 127.0.0.1/127.255.255.255 may not work for the EPICSv7 built-in pvaServer due to an issue in the implementation, in which case try a different local IP. https://epics.anl.gov/tech-talk/2021/msg00806.php&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-14/12-docs/CAref.html EPICS Channel Access Reference Manual (v3.14)]&lt;br /&gt;
* [https://mdavidsaver.github.io/pvxs/netconfig.html PVXS (PVA) Network Configuration Information]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=744</id>
		<title>Beamline Controls</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=744"/>
		<updated>2023-12-23T02:53:24Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Fix databases -&amp;gt; database&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;WIKI for the APS Beamline Controls Community, maintained by the Beamline Controls Technical Working Group.&amp;lt;br /&amp;gt;&lt;br /&gt;
This wiki exists to collect the output of the working group, including documentation on beamline controls software and hardware useful for APS beamline scientists and resident users.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Documentation===&lt;br /&gt;
&lt;br /&gt;
* [[EPICS Cheat Sheet]]: Channel Access command-lines, noteworthy record fields &amp;amp; IOC shell commands.&lt;br /&gt;
* [[EPICS 101]]: definition of basic EPICS components ([[EPICS_101#What_is_an_IOC.3F|IOC]], [[EPICS 101#What_is_a_PV.3F|PV]], [[EPICS_101#What_is_a_record.3F|record]], [[EPICS 101#What_is_a_database.3F|database]]).&lt;br /&gt;
* [[IOC 101]]: learn how to create your own IOC.&lt;br /&gt;
* [[EPICS networking]]: basic overview of how to control the network paths used by EPICS IOCs and clients.&lt;br /&gt;
* [[Git_101|Git 101]]&lt;br /&gt;
* [[Controls Software Documentation]]&lt;br /&gt;
* [[Hardware and IT Configuration]]&lt;br /&gt;
&lt;br /&gt;
===Practical Beamline Controls Training (2023)===&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Basics|Session 1: IOC Basics]]&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Deployment_.26_Troubleshooting|Session 2: IOC Deployment &amp;amp; Troubleshooting]]&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Technical Working Group information===&lt;br /&gt;
&lt;br /&gt;
The BC Technical Working (BCTWG) group meets monthly to review and gather feedback on possible changes in either the way BC delivers support or the technologies that BC supports. The BCTWG comprises the BC group plus interested stakeholders from XSD. In a nutshell, the main goal of the BCTWG is to improve communication between BC and its customers on topics of mutual interest.&lt;br /&gt;
&lt;br /&gt;
* Box folder with slides and meeting notes (ANL only): [https://anl.box.com/s/chcn7xauil93inay8ipinbxtcckc9k9f]&lt;br /&gt;
&lt;br /&gt;
* Current chairs:&lt;br /&gt;
** Kevin Peterson (XSD-BC)&lt;br /&gt;
** Tejas Guruswamy (XSD-DET)&lt;br /&gt;
** Andrew Chuang (XSD-MPE)&lt;br /&gt;
&lt;br /&gt;
===Beamline Data Pipelines===&lt;br /&gt;
&lt;br /&gt;
* https://git.aps.anl.gov/groups/bdp-public/-/wikis/home&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_101&amp;diff=743</id>
		<title>EPICS 101</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_101&amp;diff=743"/>
		<updated>2023-12-23T02:52:51Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Adjust link text&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is EPICS? ==&lt;br /&gt;
&lt;br /&gt;
EPICS (Experimental Physics and Industrial Control System) is a control system built around programs serving Process Variables (PVs) over a computer network. It is free, open source, and in active development and used in a number of large industrial and research facilities around the world.&lt;br /&gt;
EPICS is a '''distributed''' control system, which means that the IOC (software) can run on a different computer as the user interfaces.&lt;br /&gt;
&lt;br /&gt;
This page is dedicated to the definition of basic EPICS components ([[EPICS_101#What_is_an_IOC.3F|IOC]], [[EPICS_101#What_is_a_PV.3F|PV]], [[EPICS_101#What_is_a_record.3F|record]], [[EPICS_101#What_is_a_database.3F|database]]). To build your own EPICS support, you can skip directly to [[IOC_101|How does one create an IOC]].&lt;br /&gt;
&lt;br /&gt;
== What is an IOC? ==&lt;br /&gt;
&lt;br /&gt;
An EPICS '''IOC''' (Input/Output Controller) is a program which processes and serves a '''database'''. A database consists of many '''records''' each with their own '''fields''' which may contain data or change the record behavior. Each of these elements (fields) is known as a '''process variable (PV)'''. Databases may be written from scratch for the IOC or composed from pre-written EPICS '''module''' databases and record types.&lt;br /&gt;
&lt;br /&gt;
Any client, locally or on the network, can read and/or write a process variable using either '''channel access''' (CA) or '''PVaccess''' (PVA) network protocols. Clients might be another IOC, a GUI display manager (medm/caqtdm/CSS), or any other program with support for the EPICS protocols. Only the name of the process variable (in the form &amp;lt;code&amp;gt;'''prefix:record_name.field_name'''&amp;lt;/code&amp;gt;) is required to read or write a PV.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* IOCs used to run on VMEs, but nowadays it runs on anything. &lt;br /&gt;
* IOCs usually talks to hardware, but that isn’t a requirement.&lt;br /&gt;
&lt;br /&gt;
You interact directly with a running IOC via the EPICS shell ('''iocsh'''), or indirectly by reading and writing Process Variables. Starting an IOC on a general purpose computer (a '''softIOC''', as opposed to running on dedicated hardware like VME) involves running a binary along with a startup script of iocsh commands (usually called '''st.cmd''').&lt;br /&gt;
This script tells the IOC what database files to load and where those files are. When the IOC is told to load a database, it basically parses that database file, identifying the records that are contained within, and then generating the actual epics PVs that a user will interact with.&lt;br /&gt;
&lt;br /&gt;
'''Records''' and '''databases''' (lists of records) are configuration files describing the initial setup for '''PVs'''; the '''IOC''' is the software that manages the behavior of PVs and communication to get/set their values.&lt;br /&gt;
&lt;br /&gt;
== What is a PV? ==&lt;br /&gt;
&lt;br /&gt;
PV (Process Variable) is a the field from a record: &lt;br /&gt;
 '''PV = record_name + . + field_name'''&lt;br /&gt;
&lt;br /&gt;
Most of the interactive parts of user displays have PVs associated with them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a record? ==&lt;br /&gt;
&lt;br /&gt;
Records are the building blocks of EPICS:&lt;br /&gt;
* There is a lot of different types of record, and each type is designed to perform a specific function &lt;br /&gt;
* Records are customizable via fields that allow users to configure how they behave and monitor their state (see [[EPICS_Cheat_Sheet#Noteworthy_fields|Noteworthy Fields]] &amp;amp; [[#How to find more info about record fields]] to know how to learn about record fields)&lt;br /&gt;
* Records do nothing until they are processed (see [[#SCAN, PROC &amp;amp; FLNK fields]])&lt;br /&gt;
* Records vary significantly in complexity (see [[#More about records]])&lt;br /&gt;
* It is rare for new records to be created, now that [https://github.com/epics-modules/asyn''asyn''] device support exists).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Where do records come from? ===&lt;br /&gt;
&lt;br /&gt;
Typically, records at the APS comes from either:&lt;br /&gt;
* '''[https://epics.anl.gov/base/index.php EPICS base]''': main core of EPICS&lt;br /&gt;
* '''[https://www.aps.anl.gov/BCDA/synApps synApps]''': a collection of EPICS modules that are commonly used at the APS&lt;br /&gt;
A module is similar to a python package: it is an already written set of databases and associated behavior you can load into your IOC to do certain things, for example talk to specific hardware. An IOC can link to several modules.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ Records in synApps modules &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Module !! Records !! Module !! Records&lt;br /&gt;
|-&lt;br /&gt;
| alive || alive || motor || motor&lt;br /&gt;
|-&lt;br /&gt;
| asyn || asyn || optics || table&lt;br /&gt;
|-&lt;br /&gt;
| busy || busy || scaler || scaler&lt;br /&gt;
|-&lt;br /&gt;
| calc || acalcout, scalcout, sseq, swait, transform || sscan || sscan&lt;br /&gt;
|-&lt;br /&gt;
| camac || camac || std || epid, timestamp, throttle&lt;br /&gt;
|-&lt;br /&gt;
| lua || luascript || vac || digitel, vs&lt;br /&gt;
|-&lt;br /&gt;
| mca || mca || vme || vme&lt;br /&gt;
|-&lt;br /&gt;
| allenBradley || ab1771IFE, ab1771N, ab1771IX, ...|| allenBradley || ..., ab1791, abDcm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If a record isn't listed here, it probably comes from EPICS base. &lt;br /&gt;
The advantage to using synApps over a collection of modules one assembles on their own is that some amount of BCDA testing has been done.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What is a record field? ===&lt;br /&gt;
&lt;br /&gt;
Record fields are controllable or informative properties of a record. For a list of noteworthy fields, see the [[EPICS_Cheat_Sheet#Noteworthy_fields|EPICS cheat sheet]].&lt;br /&gt;
&lt;br /&gt;
==== SCAN, PROC &amp;amp; FLNK fields ====&lt;br /&gt;
&lt;br /&gt;
Records do nothing until they are processed. Records can be processed multiple ways:&lt;br /&gt;
* &amp;lt;u&amp;gt;Manually&amp;lt;/u&amp;gt;:&lt;br /&gt;
** Write 1 (or any non-zero value) to a record’s '''PROC''' field&lt;br /&gt;
**Forward link ('''FLNK''') from another record&lt;br /&gt;
* &amp;lt;u&amp;gt;Periodically&amp;lt;/u&amp;gt; by setting the '''SCAN''' field to something other than &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ SCAN field options &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Index !! Option !! Index !! Option&lt;br /&gt;
|-&lt;br /&gt;
| 0 || &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;   || 5 || &amp;lt;code&amp;gt;2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt;     || 6 || &amp;lt;code&amp;gt;1 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2 || &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt;  ||7 || &amp;lt;code&amp;gt;0.5 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 3 || &amp;lt;code&amp;gt;10 second&amp;lt;/code&amp;gt;  ||8 || &amp;lt;code&amp;gt;0.2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4 || &amp;lt;code&amp;gt;5 second&amp;lt;/code&amp;gt;  ||9 || &amp;lt;code&amp;gt;0.1 second&amp;lt;/code&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* If a record’s '''SCAN''' field is not specified in a database, it defaults to &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.  &lt;br /&gt;
* The '''SCAN''' field is common to ''all'' record types and the options can be selected by index or by string.&lt;br /&gt;
* &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt; processes a record when the driver gets a new value, but is device/driver dependent and isn’t guaranteed to work&lt;br /&gt;
&lt;br /&gt;
=== Record link types ===&lt;br /&gt;
&lt;br /&gt;
Much of the power of EPICS comes from the ability to link EPICS records together.&lt;br /&gt;
There are two link implementations: standard and dynamic.  &lt;br /&gt;
* Dynamic links (pink in standard BCDA screens) are found on ''userCalc'' ('''swait''' records) and ''scan'' ('''sscan''' records) screens; this type of link accept only a PV name. The role of the process command (see below) is taken in a separate field.   &lt;br /&gt;
* Standard links (purple in standard BCDA screens) are found everywhere else.&lt;br /&gt;
''inlinkHelp'' and ''outlinkHelp'' are accessible from userTransform screens and scaler screens (for the later only).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Input Links ====&lt;br /&gt;
&lt;br /&gt;
Input links read a value from another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an input link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just read the value; don't process the target record (i.e. read a potentially stale value); this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Process the target record and then read a value from it.&lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Read a value without causing processing to occur.&lt;br /&gt;
* &amp;lt;code&amp;gt;CP&amp;lt;/code&amp;gt; - Process linking record every time the target record processes.&lt;br /&gt;
* &amp;lt;code&amp;gt;CPP&amp;lt;/code&amp;gt; - Same as CP, but linking record process only if its SCAN field has the value &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: ''inlinkHelp'' is accessible from userTransform screens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Output Links ====&lt;br /&gt;
&lt;br /&gt;
Output links write a value to another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an output link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just write a value; don't process the target record; this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Write a value and then process the target record. To be used if you want EPICS to wait for completion. When the target record get processed, EPICS will trace it. &lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Write a value; let the target record decide whether or not to process (as it would if you typed the value by hand); if the processing does occur, EPICS will not trace it. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: &lt;br /&gt;
* The default link process command, &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;, is '''almost never the desired behavior''' for output links. Change &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; immediately and revert if problems are discovered.&lt;br /&gt;
* If the target PV is itself a link field, you must specify the command &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt;; if you want to '''wait for completion''' in this case, you must use either the '''sseq''' or the '''sCalcout''' record, select &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; and set the link's '''WAIT''' field to &amp;lt;code&amp;gt;Wait&amp;lt;/code&amp;gt;&lt;br /&gt;
* ''outlinkHelp'' is accessible from userTransform and scaler screens.&lt;br /&gt;
&lt;br /&gt;
==== Forward Links ====&lt;br /&gt;
&lt;br /&gt;
Forward links look like output links; they are purple on user displays, but they don't auto-populate with process &amp;amp; alarm commands. &lt;br /&gt;
Forward links cause the linked record to process when the record containing the forward link is processed:&lt;br /&gt;
* Linked record is in the same IOC ('''PROC''' field for linked record is optional):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
* Linked record is in a different IOC ('''PROC''' field for linked record is required):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* Forwarding-linking records in the same IOC by only specifying the record name is an exception to the &amp;quot;'''VAL''' ''is the default field''&amp;quot; rule.&lt;br /&gt;
* When omitting the '''PROC''' field of a linked record in a different IOC, nothing will happen but you won't get any error message.&lt;br /&gt;
* Always specify the '''PROC''' field to avoid problems.&lt;br /&gt;
&lt;br /&gt;
=== More about records ===&lt;br /&gt;
&lt;br /&gt;
* Records vary significantly in complexity; one way to classify them would be (*):&lt;br /&gt;
** Simple records are associated with individual data types&lt;br /&gt;
*::;bi, bo, mbbi, mbbo, longin, longout, ai, ao, stringin, stringout, waveform&lt;br /&gt;
** Intermediate records often perform calculations or link multiple records&lt;br /&gt;
*::;calcout, scalcout, acalcout, swait, transform, fanout, dfanout&lt;br /&gt;
** Complex records are associated with devices or higher-level functionality&lt;br /&gt;
*::;motor, scaler, mca, sscan, table, digitel, vs&lt;br /&gt;
** Flexible records allow custom functionality to be implemented&lt;br /&gt;
*::;sub, aSub, luascript&lt;br /&gt;
(*) this is not an official classification, nor an exhaustive list of records.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* areaDetector databases are composed of mostly simple record.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How to find more info about record fields ===&lt;br /&gt;
&lt;br /&gt;
To find documentation for a specific field you need to know/find answers to the following questions:&lt;br /&gt;
* Is the field common to all record or only input/output record types?  &lt;br /&gt;
* If not, does the record come from EPICS base or a different EPICS module (synApps)?&lt;br /&gt;
** The [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation] is the best place to find information about record types that come from EPICS base. &amp;lt;br&amp;gt;Field documentation appears in multiple locations:&lt;br /&gt;
*** Fields common to all record types&lt;br /&gt;
*** Fields common to input record types&lt;br /&gt;
*** Fields common to output record types&lt;br /&gt;
*** Record-specific documentation&lt;br /&gt;
** synApps record reference documentation&lt;br /&gt;
*** In each module's documentation directory&lt;br /&gt;
**** https://github.com/epics-modules&lt;br /&gt;
**** &amp;lt;code&amp;gt;/APSshare/epics/synApps_X_Y/support&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is a database? ==&lt;br /&gt;
&lt;br /&gt;
A database is just a text file with a '''.db''' (or '''.template''') extension containing a collection of records that are related. &lt;br /&gt;
&lt;br /&gt;
Databases are generalized with macros to allow multiple instances to be loaded (e.g. $(P)):&lt;br /&gt;
* Macros are variables containing strings to be substituted when the database is loaded.&lt;br /&gt;
* Macros without default values are required to load the database; there is no easy way to figure out what those are for a given database other than looking at the file itself.&lt;br /&gt;
* Macros required by the database should match the macros required by associated screens &amp;amp; autosave (.req) files.&lt;br /&gt;
* The P (prefix) macro usually includes a colon (:), which is the standard separator used in PV names.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How are databases loaded? ===&lt;br /&gt;
&lt;br /&gt;
There are 2 ways to load databases which are strictly equivalent.&lt;br /&gt;
&lt;br /&gt;
==== dbLoadRecords ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam1,PORT=serial1,A=01&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam2,PORT=serial1,A=02&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== dbLoadTemplate ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadTemplate(&amp;quot;substitutions/ADAM_4018.substitutions&amp;quot;,&amp;quot;P=kmp:&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ADAM_4018.substitutions:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;file &amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;&lt;br /&gt;
 {&lt;br /&gt;
 pattern&lt;br /&gt;
 {R,PORT,A}&lt;br /&gt;
 {adam1, serial1,01}&lt;br /&gt;
 {adam2, serial1,02}&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What's next? ==&lt;br /&gt;
&lt;br /&gt;
To learn how to create your own IOC, go to [[IOC 101]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-16/2-docs/AppDevGuide/DatabaseDefinition.html#x7-2630006.6 https://epics.anl.gov/]&lt;br /&gt;
* [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=742</id>
		<title>Beamline Controls</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=742"/>
		<updated>2023-12-23T02:45:20Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Beamline Controls Documentation */ add epics networking page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;WIKI for the APS Beamline Controls Community, maintained by the Beamline Controls Technical Working Group.&amp;lt;br /&amp;gt;&lt;br /&gt;
This wiki exists to collect the output of the working group, including documentation on beamline controls software and hardware useful for APS beamline scientists and resident users.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Documentation===&lt;br /&gt;
&lt;br /&gt;
* [[EPICS Cheat Sheet]]: Channel Access command-lines, noteworthy record fields &amp;amp; IOC shell commands.&lt;br /&gt;
* [[EPICS 101]]: definition of basic EPICS components ([[EPICS_101#What_is_an_IOC.3F|IOC]], [[EPICS 101#What_is_a_PV.3F|PV]], [[EPICS_101#What_is_a_record.3F|record]], [[EPICS 101#What_is_a_databases.3F|database]]).&lt;br /&gt;
* [[IOC 101]]: learn how to create your own IOC.&lt;br /&gt;
* [[EPICS networking]]: basic overview of how to control the network paths used by EPICS IOCs and clients.&lt;br /&gt;
* [[Git_101|Git 101]]&lt;br /&gt;
* [[Controls Software Documentation]]&lt;br /&gt;
* [[Hardware and IT Configuration]]&lt;br /&gt;
&lt;br /&gt;
===Practical Beamline Controls Training (2023)===&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Basics|Session 1: IOC Basics]]&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Deployment_.26_Troubleshooting|Session 2: IOC Deployment &amp;amp; Troubleshooting]]&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Technical Working Group information===&lt;br /&gt;
&lt;br /&gt;
The BC Technical Working (BCTWG) group meets monthly to review and gather feedback on possible changes in either the way BC delivers support or the technologies that BC supports. The BCTWG comprises the BC group plus interested stakeholders from XSD. In a nutshell, the main goal of the BCTWG is to improve communication between BC and its customers on topics of mutual interest.&lt;br /&gt;
&lt;br /&gt;
* Box folder with slides and meeting notes (ANL only): [https://anl.box.com/s/chcn7xauil93inay8ipinbxtcckc9k9f]&lt;br /&gt;
&lt;br /&gt;
* Current chairs:&lt;br /&gt;
** Kevin Peterson (XSD-BC)&lt;br /&gt;
** Tejas Guruswamy (XSD-DET)&lt;br /&gt;
** Andrew Chuang (XSD-MPE)&lt;br /&gt;
&lt;br /&gt;
===Beamline Data Pipelines===&lt;br /&gt;
&lt;br /&gt;
* https://git.aps.anl.gov/groups/bdp-public/-/wikis/home&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=741</id>
		<title>EPICS networking</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_networking&amp;diff=741"/>
		<updated>2023-12-23T02:40:52Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Writeup of BDP presentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EPICS networking =&lt;br /&gt;
&lt;br /&gt;
For basic terminology, see [[EPICS 101]].&lt;br /&gt;
&lt;br /&gt;
An EPICS IOC is an application which serves EPICS clients (command-line programs like caget; applications using p4p, pyepics, pvapy, or other libraries; GUI display managers like MEDM or caQtDM) process variables over the network. They do so using either the Channel Access (CA) or PVAccess (PVA) network protocols.&lt;br /&gt;
&lt;br /&gt;
By default, an EPICS IOC with CA and/or PVA support enabled will listen for clients on '''all available network interfaces​.'''&lt;br /&gt;
&lt;br /&gt;
== Connection Flow ==&lt;br /&gt;
&lt;br /&gt;
* A client emits a request for particular PV names, e.g. ''13SIM1:cam1:Image​''.&lt;br /&gt;
* Any IOC which receives the request and provides any PV name requested will respond to the client​.&lt;br /&gt;
* The client and Server now know each other's IP addresses​.&lt;br /&gt;
* A one-to-one communications channel between client and server is established​.&lt;br /&gt;
* The opened Channel is used for either a one-off READ or WRITE, or a SUBSCRIPTION (monitor) to receive an update every time the PV value changes​.&lt;br /&gt;
&lt;br /&gt;
This flow is more or less the same for the CA or PVA protocols​, and involves a mix of TCP/IP and UDP/IP transport with varying port numbers. Many client libraries (e.g. pyepics) will cache connections, or convert repeated READs into SUBSCRIPTIONS behind-the-scenes to save resources.&lt;br /&gt;
&lt;br /&gt;
This system ensures that a newly-started IOC is immediately accessible to all clients without needing to register with a central server, and the only information you need to connect to a PV is its full name.&lt;br /&gt;
&lt;br /&gt;
== The search request ==&lt;br /&gt;
&lt;br /&gt;
EPICS clients follow a simple two-step process to construct the destination of a PV search request. This is performed separately for CA and PVA protocols (substitute ''either'' &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PVA&amp;lt;/code&amp;gt; into the names of the environment variables described below).&lt;br /&gt;
&lt;br /&gt;
# Start with an empty list.&lt;br /&gt;
# If the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=yes&amp;lt;/code&amp;gt;, then add all broadcast IP addresses for all available network interfaces to the list.&lt;br /&gt;
#* &amp;quot;yes&amp;quot; is the default value if unset.&lt;br /&gt;
#* To skip this step, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Add the contents of the environment variable &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the list.&lt;br /&gt;
#* This should be a space-separated list of IP addresses or hostnames.&lt;br /&gt;
# Send the PV search request to every IP or host in the list.&lt;br /&gt;
&lt;br /&gt;
Environment variables should be set prior to starting the client program to be effective, and may need to be &amp;quot;exported&amp;quot; to persist (depending on your shell). Example in bash:&lt;br /&gt;
&lt;br /&gt;
    export EPICS_CA_AUTO_ADDR_LIST=no EPICS_CA_ADDR_LIST=s1pvgate.xray.aps.anl.gov&lt;br /&gt;
    caget 1BM:ExampleVariable&lt;br /&gt;
&lt;br /&gt;
== Potential issues ==&lt;br /&gt;
=== Crossing subnet boundaries ===&lt;br /&gt;
&lt;br /&gt;
Since by default only broadcast addresses are in the search request destination list, and broadcast packets are not routed between subnets, without extra configuration you will only be able to find PVs on the same subnet as your client.&lt;br /&gt;
&lt;br /&gt;
;Solution 1&amp;amp;#58; add the IP address of the IOC server directly to &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt;.&lt;br /&gt;
:This works across subnet boundaries as long as the required ports are available (no firewalls), but doesn't scale well if there are many IOCs you want to connect to.&lt;br /&gt;
&lt;br /&gt;
;Solution 2&amp;amp;#58; set up a PV Gateway server in the IOC subnet, and add the PV gateway IP address&lt;br /&gt;
:A [https://github.com/epics-extensions/ca-gateway PV gateway] is a dedicated server program which relays incoming requests on to the rest of the subnet. It can also apply security rules to the traffic it is forwarding, e.g. it can force a PV to be read-only. The PV gateway hostname or IP address must be added to the relevant &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
; Solution 3&amp;amp;#58; set up a PV nameserver.&lt;br /&gt;
:Similar to DNS, the [https://github.com/epics-extensions/ca-nameserver nameserver] is a server program that takes over responding to all client name search requests. In this setup, the nameserver must be added to the &amp;lt;code&amp;gt;ADDR_LIST&amp;lt;/code&amp;gt; for all clients.&lt;br /&gt;
&lt;br /&gt;
=== Multiple paths between client and server ===&lt;br /&gt;
&lt;br /&gt;
An IOC will reply to '''all''' requests for PVs it servers, even multiple ones from the same client.&lt;br /&gt;
&lt;br /&gt;
Therefore if there are multiple network paths from client to server, for example because the client and/or server have multiple network interfaces, the server may see multiple requests from the client and the client will get multiple responses, each with a different IP.&lt;br /&gt;
&lt;br /&gt;
The same situation can occur if multiple IOCs are serving a PV with the exact same name. The client will usually pick the first response it receives and print a warning to the user, for example:&lt;br /&gt;
&lt;br /&gt;
    12-12-2023 01:36:01 Channel Access Exception Channel: &amp;quot;bdpSim0:cam1:Model_RBV&amp;quot;, Connecting to: beryl-gpm.xray.aps.anl.gov:5064, Ignored: 10.0.0.1:5064 on ? (op=5 data_type=DBR_invalid count=0) &lt;br /&gt;
&lt;br /&gt;
Which server IP is selected is essentially random each time a search request completes and a connection is created, and there is no guarantee it is the optimal or fastest path from client to server.&lt;br /&gt;
&lt;br /&gt;
;Solution&amp;amp;#58; limit EPICS traffic to only one interface and one network path.&lt;br /&gt;
:On the client, set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_AUTO_ADDR_LIST=no&amp;lt;/code&amp;gt; and manually set &amp;lt;code&amp;gt;EPICS_{CA,PVA}_ADDR_LIST&amp;lt;/code&amp;gt; to the single broadcast address on the network interface you want to use.&lt;br /&gt;
&lt;br /&gt;
It is also possible to set &amp;lt;code&amp;gt;EPICS_{CA,PVA}S_INTF_ADDR_LIST&amp;lt;/code&amp;gt; on the server to limit the addresses the IOC listens on, but this must be done ''before'' starting the IOC.&lt;br /&gt;
&lt;br /&gt;
The most common variant of this situation is when the client and server are on the same computer. In this case, all the available network interfaces (including the loopback interface ''lo'') present a valid path from client to server.&lt;br /&gt;
&lt;br /&gt;
To limit all traffic to only travel over the loopback interface (which will be the fastest), before running your client set:&lt;br /&gt;
&lt;br /&gt;
   EPICS_CA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_PVA_ADDR_LIST=127.255.255.255​&lt;br /&gt;
   EPICS_CA_AUTO_ADDR_LIST=no​&lt;br /&gt;
   EPICS_PVA_AUTO_ADDR_LIST=no&lt;br /&gt;
&lt;br /&gt;
The difference between using only the loopback address (127.0.0.1) and using the loopback broadcast address (127.255.255.255) is that the broadcast address supports communicating with multiple IOCs on the same host on Linux. See the [https://docs.epics-controls.org/en/latest/sys-admin/channel-access-reach-multiple-soft-iocs-linux.html EPICS documentation] for more details and alternative solutions.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://epics.anl.gov/base/R3-14/12-docs/CAref.html EPICS Channel Access Reference Manual (v3.14)]&lt;br /&gt;
* [https://mdavidsaver.github.io/pvxs/netconfig.html PVXS (PVA) Network Configuration Information]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=NVIDIA_Data_Processing_Units&amp;diff=580</id>
		<title>NVIDIA Data Processing Units</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=NVIDIA_Data_Processing_Units&amp;diff=580"/>
		<updated>2023-05-17T18:50:31Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
NVIDIA DPUs are expansion cards which allow for offloading of certain network-traffic related tasks from the host CPU. They comprise of an ARM CPU, memory, and high-speed ConnectX NIC on the same board.&lt;br /&gt;
Network packets to/from the host can be manipulated by the ARM CPU using programs written with the DPDK or DOCA SDKs.&lt;br /&gt;
The DPU ARM system runs its own OS; as shipped by NVIDIA, this is currently Ubuntu Linux.&lt;br /&gt;
&lt;br /&gt;
== DPU host software setup ==&lt;br /&gt;
&lt;br /&gt;
[https://docs.nvidia.com/networking/display/BlueField2DPUVPI/BlueField+DPU+Administrator+Quick+Start+Guide Bluefield DPU Administrator Quick Start Guide] (NVIDIA)&lt;br /&gt;
&lt;br /&gt;
On a RHEL8 machine, first install the RPM package which contains the DOCA and DPU-related packages. This includes both a local copy of the necessary RPMs and enables a YUM repo for updates.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ wget https://www.mellanox.com/downloads/DOCA/DOCA_v1.5.1/doca-host-repo-rhel86-1.5.1-0.1.8.1.5.1007.1.el8.5.8.1.1.2.1.x86_64.rpm&lt;br /&gt;
# yum install ./doca-host-repo-rhel86-1.5.1-0.1.8.1.5.1007.1.el8.5.8.1.1.2.1.x86_64.rpm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We find that the NVIDIA repos tend to timeout when accessed from the APS, so add to the end of &amp;lt;code&amp;gt;/etc/yum.conf&amp;lt;/code&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;minrate=10 &lt;br /&gt;
timeout=300&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then install the necessary RPMs, allowing for downgrades and package removals:&lt;br /&gt;
&amp;lt;pre&amp;gt;# yum makecache &lt;br /&gt;
# yum install --allowerasing --nobest doca-runtime doca-tools pv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rshim&amp;lt;/code&amp;gt; is a userspace tool which allows for configuration of NVIDIA Mellanox cards.&lt;br /&gt;
Ensure rshim is running with &amp;lt;code&amp;gt;systemctl status rshim&amp;lt;/code&amp;gt; (look for &amp;quot;loaded&amp;quot; and &amp;quot;enabled&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mst&amp;lt;/code&amp;gt;, or Mellanox Software Tools, is a userspace program which creates a device tree used for configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# mst start &lt;br /&gt;
Starting MST (Mellanox Software Tools) driver set &lt;br /&gt;
Loading MST PCI module - Success &lt;br /&gt;
Loading MST PCI configuration module - Success &lt;br /&gt;
Create devices &lt;br /&gt;
Unloading MST PCI module (unused) - Success &lt;br /&gt;
# mst status -v &lt;br /&gt;
MST modules: &lt;br /&gt;
------------ &lt;br /&gt;
    MST PCI module is not loaded &lt;br /&gt;
    MST PCI configuration module loaded &lt;br /&gt;
PCI devices: &lt;br /&gt;
------------ &lt;br /&gt;
DEVICE_TYPE             MST                           PCI       RDMA            NET                       NUMA   &lt;br /&gt;
BlueField2(rev:1)       /dev/mst/mt41686_pciconf0     ca:00.0   mlx5_0          net-ib0                   1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a new Bluefield OS system image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ wget https://content.mellanox.com/BlueField/BFBs/Ubuntu20.04/DOCA_1.5.1_BSP_3.9.3_Ubuntu_20.04-4.2211-LTS.signed.bfb&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and install it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# bfb-install --bfb DOCA_1.5.1_BSP_3.9.3_Ubuntu_20.04-4.2211-LTS.signed.bfb --rshim rshim0&lt;br /&gt;
Collecting BlueField booting status. Press Ctrl+C to stop… &lt;br /&gt;
INFO[BL2]: start &lt;br /&gt;
INFO[BL2]: DDR POST passed &lt;br /&gt;
INFO[BL2]: UEFI loaded &lt;br /&gt;
INFO[BL31]: start &lt;br /&gt;
INFO[BL31]: runtime &lt;br /&gt;
INFO[UEFI]: UPVS valid &lt;br /&gt;
INFO[UEFI]: eMMC init &lt;br /&gt;
INFO[UEFI]: eMMC probed &lt;br /&gt;
INFO[UEFI]: PMI: updates started &lt;br /&gt;
INFO[UEFI]: PMI: boot image update &lt;br /&gt;
INFO[UEFI]: PMI: updates completed, status 0 &lt;br /&gt;
INFO[UEFI]: PCIe enum start &lt;br /&gt;
INFO[UEFI]: PCIe enum end &lt;br /&gt;
INFO[MISC]: Ubuntu installation started &lt;br /&gt;
INFO[MISC]: Installing OS image &lt;br /&gt;
INFO[MISC]: Installation finished&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only if DPU remote access (LAN/internet) is required, enable ip routing on host: add to &amp;lt;code&amp;gt;/etc/sysctl.d/50-dpu.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;net.ipv4.conf.all.forwarding = 1 &lt;br /&gt;
net.ipv6.conf.all.forwarding = 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and setup IPv4 masquerading via nftables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# nft add table nat &lt;br /&gt;
# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } &lt;br /&gt;
# nft -- add chain nat postrouting { type nat hook postrouting priority 100 \; } &lt;br /&gt;
# nft add rule nat postrouting oifname &amp;quot;ens6f0&amp;quot; snat to $(host IP) &lt;br /&gt;
# nft list ruleset &amp;gt; /etc/nftables/dpu_nat.nft &lt;br /&gt;
# echo &amp;quot;include &amp;quot;/etc/nftables/dpu_nat.nft&amp;quot; &amp;gt;&amp;gt; /etc/sysconfig/nftables.conf &lt;br /&gt;
# systemctl enable nftables.service&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPU login and configuration ==&lt;br /&gt;
&lt;br /&gt;
First set up an appropriate IP configuration for the tmfifo_net0 interface on the host. The DPU is factory-configured at 192.168.100.2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# nmcli conn add type tun mode tap con-name tmfifo_net0 ifname tmfifo_net0 autoconnect yes ip4 192.168.100.1/24 ipv4.never-default true &lt;br /&gt;
# nmci conn up tmfifo_net0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then login via ssh:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ ssh ubuntu@192.168.100.2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should receive the Ubuntu OS login prompt, and will be prompted to update the user password.&lt;br /&gt;
&lt;br /&gt;
You can now update the DPU firmware:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# sudo /opt/mellanox/mlnx-fw-updater/mlnx_fw_updater.pl&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and configure it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sudo mst start&lt;br /&gt;
# sudo mlxconfig -d /dev/mst/mt41686_pciconf0 -y reset   # Reset all settings&lt;br /&gt;
# sudo mlxconfig -d /dev/mst/mt41686_pciconf0 s LINK_TYPE_P1=2    # Set port 1 to Ethernet mode (not Infiniband)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reboot the host and ensure settings persist.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Modes+of+Operation BlueField Modes of Operation]&lt;br /&gt;
* [https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Functional+Diagram BlueField Functional Diagram]&lt;br /&gt;
* [https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Kernel+Representors+Model BlueField Kernel Representors] (names for the passthrough interfaces from the DPU side)&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=NVIDIA_Data_Processing_Units&amp;diff=579</id>
		<title>NVIDIA Data Processing Units</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=NVIDIA_Data_Processing_Units&amp;diff=579"/>
		<updated>2023-05-17T18:49:43Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
NVIDIA DPUs are expansion cards which allow for offloading of certain network-traffic related tasks from the host CPU. They comprise of an ARM CPU, memory, and high-speed ConnectX NIC on the same board.&lt;br /&gt;
Network packets to/from the host can be manipulated by the ARM CPU using programs written with the DPDK or DOCA SDKs.&lt;br /&gt;
The DPU ARM system runs its own OS; as shipped by NVIDIA, this is currently Ubuntu Linux.&lt;br /&gt;
&lt;br /&gt;
== DPU host software setup ==&lt;br /&gt;
&lt;br /&gt;
[https://docs.nvidia.com/networking/display/BlueField2DPUVPI/BlueField+DPU+Administrator+Quick+Start+Guide Bluefield DPU Administrator Quick Start Guide] (NVIDIA)&lt;br /&gt;
&lt;br /&gt;
On a RHEL8 machine, first install the RPM package which contains the DOCA and DPU-related packages. This includes both a local copy of the necessary RPMs and enables a YUM repo for updates.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ wget https://www.mellanox.com/downloads/DOCA/DOCA_v1.5.1/doca-host-repo-rhel86-1.5.1-0.1.8.1.5.1007.1.el8.5.8.1.1.2.1.x86_64.rpm&lt;br /&gt;
# yum install ./doca-host-repo-rhel86-1.5.1-0.1.8.1.5.1007.1.el8.5.8.1.1.2.1.x86_64.rpm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We find that the NVIDIA repos tend to timeout when accessed from the APS, so add to the end of &amp;lt;code&amp;gt;/etc/yum.conf&amp;lt;/code&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;minrate=10 &lt;br /&gt;
timeout=300&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then install the necessary RPMs, allowing for downgrades and package removals:&lt;br /&gt;
&amp;lt;pre&amp;gt;# yum makecache &lt;br /&gt;
# yum install --allowerasing --nobest doca-runtime doca-tools pv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rshim&amp;lt;/code&amp;gt; is a userspace tool which allows for configuration of NVIDIA Mellanox cards.&lt;br /&gt;
Ensure rshim is running with &amp;lt;code&amp;gt;systemctl status rshim&amp;lt;/code&amp;gt; (look for &amp;quot;loaded&amp;quot; and &amp;quot;enabled&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mst&amp;lt;/code&amp;gt;, or Mellanox Software Tools, is a userspace program which creates a device tree used for configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# mst start &lt;br /&gt;
Starting MST (Mellanox Software Tools) driver set &lt;br /&gt;
Loading MST PCI module - Success &lt;br /&gt;
Loading MST PCI configuration module - Success &lt;br /&gt;
Create devices &lt;br /&gt;
Unloading MST PCI module (unused) - Success &lt;br /&gt;
# mst status -v &lt;br /&gt;
MST modules: &lt;br /&gt;
------------ &lt;br /&gt;
    MST PCI module is not loaded &lt;br /&gt;
    MST PCI configuration module loaded &lt;br /&gt;
PCI devices: &lt;br /&gt;
------------ &lt;br /&gt;
DEVICE_TYPE             MST                           PCI       RDMA            NET                       NUMA   &lt;br /&gt;
BlueField2(rev:1)       /dev/mst/mt41686_pciconf0     ca:00.0   mlx5_0          net-ib0                   1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a new Bluefield OS system image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ wget https://content.mellanox.com/BlueField/BFBs/Ubuntu20.04/DOCA_1.5.1_BSP_3.9.3_Ubuntu_20.04-4.2211-LTS.signed.bfb&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and install it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# bfb-install --bfb DOCA_1.5.1_BSP_3.9.3_Ubuntu_20.04-4.2211-LTS.signed.bfb --rshim rshim0&lt;br /&gt;
Collecting BlueField booting status. Press Ctrl+C to stop… &lt;br /&gt;
INFO[BL2]: start &lt;br /&gt;
INFO[BL2]: DDR POST passed &lt;br /&gt;
INFO[BL2]: UEFI loaded &lt;br /&gt;
INFO[BL31]: start &lt;br /&gt;
INFO[BL31]: runtime &lt;br /&gt;
INFO[UEFI]: UPVS valid &lt;br /&gt;
INFO[UEFI]: eMMC init &lt;br /&gt;
INFO[UEFI]: eMMC probed &lt;br /&gt;
INFO[UEFI]: PMI: updates started &lt;br /&gt;
INFO[UEFI]: PMI: boot image update &lt;br /&gt;
INFO[UEFI]: PMI: updates completed, status 0 &lt;br /&gt;
INFO[UEFI]: PCIe enum start &lt;br /&gt;
INFO[UEFI]: PCIe enum end &lt;br /&gt;
INFO[MISC]: Ubuntu installation started &lt;br /&gt;
INFO[MISC]: Installing OS image &lt;br /&gt;
INFO[MISC]: Installation finished&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only if DPU remote access (LAN/internet) is required, enable ip routing on host: add to &amp;lt;code&amp;gt;/etc/sysctl.d/50-dpu.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;net.ipv4.conf.all.forwarding = 1 &lt;br /&gt;
net.ipv6.conf.all.forwarding = 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and setup IPv4 masquerading via nftables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# nft add table nat &lt;br /&gt;
# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } &lt;br /&gt;
# nft -- add chain nat postrouting { type nat hook postrouting priority 100 \; } &lt;br /&gt;
# nft add rule nat postrouting oifname &amp;quot;ens6f0&amp;quot; snat to $(host IP) &lt;br /&gt;
# nft list ruleset &amp;gt; /etc/nftables/dpu_nat.nft &lt;br /&gt;
# echo &amp;quot;include &amp;quot;/etc/nftables/dpu_nat.nft&amp;quot; &amp;gt;&amp;gt; /etc/sysconfig/nftables.conf &lt;br /&gt;
# systemctl enable nftables.service&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPU login and configuration ==&lt;br /&gt;
&lt;br /&gt;
First set up an appropriate IP configuration for the tmfifo_net0 interface on the host. The DPU is factory-configured at 192.168.100.2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# nmcli conn add type tun mode tap con-name tmfifo_net0 ifname tmfifo_net0 autoconnect yes ip4 192.168.100.1/24 ipv4.never-default true &lt;br /&gt;
# nmci conn up tmfifo_net0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then login via ssh:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ ssh ubuntu@192.168.100.2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should receive the Ubuntu OS login prompt, and will be prompted to update the user password.&lt;br /&gt;
&lt;br /&gt;
You can now update the DPU firmware:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo /opt/mellanox/mlnx-fw-updater/mlnx_fw_updater.pl&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and configure it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo mst start&lt;br /&gt;
# Reset all settings&lt;br /&gt;
sudo mlxconfig -d /dev/mst/mt41686_pciconf0 -y reset &lt;br /&gt;
# Set port 1 to Ethernet mode (not Infiniband)&lt;br /&gt;
sudo mlxconfig -d /dev/mst/mt41686_pciconf0 s LINK_TYPE_P1=2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reboot the host and ensure settings persist.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Modes+of+Operation BlueField Modes of Operation]&lt;br /&gt;
* [https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Functional+Diagram BlueField Functional Diagram]&lt;br /&gt;
* [https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Kernel+Representors+Model BlueField Kernel Representors] (names for the passthrough interfaces from the DPU side)&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=NVIDIA_Data_Processing_Units&amp;diff=578</id>
		<title>NVIDIA Data Processing Units</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=NVIDIA_Data_Processing_Units&amp;diff=578"/>
		<updated>2023-05-17T18:49:27Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: DPU setup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
NVIDIA DPUs are expansion cards which allow for offloading of certain network-traffic related tasks from the host CPU. They comprise of an ARM CPU, memory, and high-speed ConnectX NIC on the same board.&lt;br /&gt;
Network packets to/from the host can be manipulated by the ARM CPU using programs written with the DPDK or DOCA SDKs.&lt;br /&gt;
The DPU ARM system runs its own OS; as shipped by NVIDIA, this is currently Ubuntu Linux.&lt;br /&gt;
&lt;br /&gt;
== DPU host software setup ==&lt;br /&gt;
&lt;br /&gt;
[https://docs.nvidia.com/networking/display/BlueField2DPUVPI/BlueField+DPU+Administrator+Quick+Start+Guide Bluefield DPU Administrator Quick Start Guide] (NVIDIA)&lt;br /&gt;
&lt;br /&gt;
On a RHEL8 machine, first install the RPM package which contains the DOCA and DPU-related packages. This includes both a local copy of the necessary RPMs and enables a YUM repo for updates.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ wget https://www.mellanox.com/downloads/DOCA/DOCA_v1.5.1/doca-host-repo-rhel86-1.5.1-0.1.8.1.5.1007.1.el8.5.8.1.1.2.1.x86_64.rpm&lt;br /&gt;
# yum install ./doca-host-repo-rhel86-1.5.1-0.1.8.1.5.1007.1.el8.5.8.1.1.2.1.x86_64.rpm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We find that the NVIDIA repos tend to timeout when accessed from the APS, so add to the end of &amp;lt;code&amp;gt;/etc/yum.conf&amp;lt;/code&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;minrate=10 &lt;br /&gt;
timeout=300&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then install the necessary RPMs, allowing for downgrades and package removals:&lt;br /&gt;
&amp;lt;pre&amp;gt;# yum makecache &lt;br /&gt;
# yum install --allowerasing --nobest doca-runtime doca-tools pv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rshim&amp;lt;/code&amp;gt; is a userspace tool which allows for configuration of NVIDIA Mellanox cards.&lt;br /&gt;
Ensure rshim is running with &amp;lt;code&amp;gt;systemctl status rshim&amp;lt;/code&amp;gt; (look for &amp;quot;loaded&amp;quot; and &amp;quot;enabled&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mst&amp;lt;/code&amp;gt;, or Mellanox Software Tools, is a userspace program which creates a device tree used for configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# mst start &lt;br /&gt;
Starting MST (Mellanox Software Tools) driver set &lt;br /&gt;
Loading MST PCI module - Success &lt;br /&gt;
Loading MST PCI configuration module - Success &lt;br /&gt;
Create devices &lt;br /&gt;
Unloading MST PCI module (unused) - Success &lt;br /&gt;
# mst status -v &lt;br /&gt;
MST modules: &lt;br /&gt;
------------ &lt;br /&gt;
    MST PCI module is not loaded &lt;br /&gt;
    MST PCI configuration module loaded &lt;br /&gt;
PCI devices: &lt;br /&gt;
------------ &lt;br /&gt;
DEVICE_TYPE             MST                           PCI       RDMA            NET                       NUMA   &lt;br /&gt;
BlueField2(rev:1)       /dev/mst/mt41686_pciconf0     ca:00.0   mlx5_0          net-ib0                   1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get a new Bluefield OS system image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ wget https://content.mellanox.com/BlueField/BFBs/Ubuntu20.04/DOCA_1.5.1_BSP_3.9.3_Ubuntu_20.04-4.2211-LTS.signed.bfb&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and install it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# bfb-install --bfb DOCA_1.5.1_BSP_3.9.3_Ubuntu_20.04-4.2211-LTS.signed.bfb --rshim rshim0&lt;br /&gt;
Collecting BlueField booting status. Press Ctrl+C to stop… &lt;br /&gt;
INFO[BL2]: start &lt;br /&gt;
INFO[BL2]: DDR POST passed &lt;br /&gt;
INFO[BL2]: UEFI loaded &lt;br /&gt;
INFO[BL31]: start &lt;br /&gt;
INFO[BL31]: runtime &lt;br /&gt;
INFO[UEFI]: UPVS valid &lt;br /&gt;
INFO[UEFI]: eMMC init &lt;br /&gt;
INFO[UEFI]: eMMC probed &lt;br /&gt;
INFO[UEFI]: PMI: updates started &lt;br /&gt;
INFO[UEFI]: PMI: boot image update &lt;br /&gt;
INFO[UEFI]: PMI: updates completed, status 0 &lt;br /&gt;
INFO[UEFI]: PCIe enum start &lt;br /&gt;
INFO[UEFI]: PCIe enum end &lt;br /&gt;
INFO[MISC]: Ubuntu installation started &lt;br /&gt;
INFO[MISC]: Installing OS image &lt;br /&gt;
INFO[MISC]: Installation finished&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only if DPU remote access (LAN/internet) is required, enable ip routing on host: add to &amp;lt;code&amp;gt;/etc/sysctl.d/50-dpu.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;net.ipv4.conf.all.forwarding = 1 &lt;br /&gt;
net.ipv6.conf.all.forwarding = 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and setup IPv4 masquerading via nftables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# nft add table nat &lt;br /&gt;
# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } &lt;br /&gt;
# nft -- add chain nat postrouting { type nat hook postrouting priority 100 \; } &lt;br /&gt;
# nft add rule nat postrouting oifname &amp;quot;ens6f0&amp;quot; snat to $(host IP) &lt;br /&gt;
# nft list ruleset &amp;gt; /etc/nftables/dpu_nat.nft &lt;br /&gt;
# echo &amp;quot;include &amp;quot;/etc/nftables/dpu_nat.nft&amp;quot; &amp;gt;&amp;gt; /etc/sysconfig/nftables.conf &lt;br /&gt;
# systemctl enable nftables.service&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DPU login and configuration ==&lt;br /&gt;
&lt;br /&gt;
First set up an appropriate IP configuration for the tmfifo_net0 interface on the host. The DPU is factory-configured at 192.168.100.2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# nmcli conn add type tun mode tap con-name tmfifo_net0 ifname tmfifo_net0 autoconnect yes ip4 192.168.100.1/24 ipv4.never-default true &lt;br /&gt;
# nmci conn up tmfifo_net0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then login via ssh:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ ssh ubuntu@192.168.100.2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should receive the Ubuntu OS login prompt, and will be prompted to update the user password.&lt;br /&gt;
&lt;br /&gt;
You can now update the DPU firmware:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo /opt/mellanox/mlnx-fw-updater/mlnx_fw_updater.pl&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and configure it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo mst start&lt;br /&gt;
# Reset all settings&lt;br /&gt;
sudo mlxconfig -d /dev/mst/mt41686_pciconf0 -y reset &lt;br /&gt;
# Set port 1 to Ethernet mode (not Infiniband)&lt;br /&gt;
sudo mlxconfig -d /dev/mst/mt41686_pciconf0 s LINK_TYPE_P1=2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reboot the host and ensure settings persist.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
[https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Modes+of+Operation BlueField Modes of Operation]&lt;br /&gt;
[https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Functional+Diagram BlueField Functional Diagram]&lt;br /&gt;
[https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest/Kernel+Representors+Model BlueField Kernel Representors] (names for the passthrough interfaces from the DPU side)&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Hardware_and_IT_Configuration&amp;diff=577</id>
		<title>Hardware and IT Configuration</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Hardware_and_IT_Configuration&amp;diff=577"/>
		<updated>2023-05-17T16:32:57Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* IT and General Computing Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page exists to collect links and resources on controls hardware and related topics useful to beamline scientists. Examples might include information on certain control equipment (detectors, motors, FPGAs, etc.), correct setup and use of networking or storage IT infrastructure (without reference to specific ANL information), and low-level configuration of operating systems and device drivers for effective operation.&lt;br /&gt;
&lt;br /&gt;
==Controls Hardware==&lt;br /&gt;
* [https://wiki.aps.anl.gov/bts/index.php?title=Main_Page Detector Pool wiki] (APS internal)&lt;br /&gt;
* [https://wiki.aps.anl.gov/bcda/index.php?title=Category:RECOMMENDED Beamline Controls group recommended hardware] (APS internal)&lt;br /&gt;
&lt;br /&gt;
==IT and General Computing Resources==&lt;br /&gt;
* [[Linux network teaming]] -- aka bonding, combining multiple network interfaces for increased network bandwidth&lt;br /&gt;
* [[NVIDIA Data Processing Units]] -- BlueField2 series initial hardware setup&lt;br /&gt;
* [[NVIDIA GPUDirect]] -- transfer data to GPU memory bypassing the CPU&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Hardware_and_IT_Configuration&amp;diff=576</id>
		<title>Hardware and IT Configuration</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Hardware_and_IT_Configuration&amp;diff=576"/>
		<updated>2023-05-17T15:23:45Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page exists to collect links and resources on controls hardware and related topics useful to beamline scientists. Examples might include information on certain control equipment (detectors, motors, FPGAs, etc.), correct setup and use of networking or storage IT infrastructure (without reference to specific ANL information), and low-level configuration of operating systems and device drivers for effective operation.&lt;br /&gt;
&lt;br /&gt;
==Controls Hardware==&lt;br /&gt;
* [https://wiki.aps.anl.gov/bts/index.php?title=Main_Page Detector Pool wiki] (APS internal)&lt;br /&gt;
* [https://wiki.aps.anl.gov/bcda/index.php?title=Category:RECOMMENDED Beamline Controls group recommended hardware] (APS internal)&lt;br /&gt;
&lt;br /&gt;
==IT and General Computing Resources==&lt;br /&gt;
* [[Linux network teaming]] -- aka bonding, combining multiple network interfaces for increased network bandwidth&lt;br /&gt;
* [[NVIDIA DPU setup]] -- BlueField2 series initial hardware setup&lt;br /&gt;
* [[NVIDIA GPUDirect setup]] -- transfer data to GPU memory bypassing the CPU&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=567</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=567"/>
		<updated>2023-05-11T17:01:35Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Maximum throughput (one-to-one) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support or cooperation required. Packets can arrive out-of-order, which may increase CPU load on the receiver or cause retransmissions -- leading to the usable bandwidth being perhaps 150% of a single link.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate TCP ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple TCP/UDP ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=566</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=566"/>
		<updated>2023-05-11T17:01:09Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Maximum throughput (one-to-one) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support or cooperation required. Packets can arrive out-of-order, which may increase CPU load on the receiver or cause retransmissions -- leading to the usable bandwidth being more like 150% of a single link.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate TCP ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple TCP/UDP ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=565</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=565"/>
		<updated>2023-05-11T17:00:03Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Maximum throughput (one-to-one) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage '''using a single network stream'''. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets can arrive out-of-order, which may increase CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate TCP ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple TCP/UDP ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=292</id>
		<title>Controls Software Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=292"/>
		<updated>2023-03-15T17:43:00Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* areaDetector */ update url&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page exists to collect links to documentation about the instrument control system EPICS, its modules and related libraries (synApps, areaDetector), as used at the Advanced Photon Source.&lt;br /&gt;
&lt;br /&gt;
Documentation referenced should be appropriate for beamline scientists, as opposed to only EPICS developers.&lt;br /&gt;
New deployments should prefer EPICSv7, the latest release series.&lt;br /&gt;
&lt;br /&gt;
See also the extensive [https://epics-controls.org/resources-and-support/documents/training/ resources from past EPICS Collaboration meetings].&lt;br /&gt;
&lt;br /&gt;
==EPICS Base==&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Intro.html Intro to EPICS]&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html EPICS Database Concepts]&lt;br /&gt;
* [https://docs.epics-controls.org/projects/how-tos/en/latest/getting-started/installation.html EPICS Base Getting Started (official)]&lt;br /&gt;
* [https://cmd-response.readthedocs.io/en/latest/epics/rpi_epics.html Installing EPICS on RaspberryPi]&lt;br /&gt;
&lt;br /&gt;
==synApps (aka EPICS Support)==&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps_docs_all.html synApps Collected Documentation]&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps.html synApps deployment instructions, including use of xxx template ioc]&lt;br /&gt;
&lt;br /&gt;
==areaDetector==&lt;br /&gt;
* [https://areadetector.github.io/areaDetector/ areaDetector Official Documentation]&lt;br /&gt;
&lt;br /&gt;
==Deploying, troubleshooting, and maintaining IOCs==&lt;br /&gt;
* [[Troubleshooting EPICS IOCs]]&lt;br /&gt;
* [https://docs2bm.readthedocs.io/en/latest/source/ops/item_000_0.html simDetector Install directions (2BM)]&lt;br /&gt;
* [https://epics-modules.github.io/xxx/overview.html The Basics of an IOC (XXX documentation)]&lt;br /&gt;
* [https://gist.github.com/keenanlang/e768774cbd0a367b96281939b8a2c9ba Creation of an IOC using mkioc]&lt;br /&gt;
* [https://wiki.aps.anl.gov/bcda/index.php/Category:TUTORIAL BCDA Tutorials (APS Internal)]&lt;br /&gt;
&lt;br /&gt;
==Pre-built IOCs==&lt;br /&gt;
===Docker images===&lt;br /&gt;
* EPICS Base 7.0.5, synApps 6.2: [https://github.com/prjemian/epics-docker/tree/main/v1.1/n3_synApps#readmemd standard xxx], [https://github.com/prjemian/epics-docker/tree/main/v1.1/n5_custom_synApps#readmemd customized]&lt;br /&gt;
* EPICS Base 7.0.5, synApps 6.2, area detector 3.10: [https://github.com/prjemian/epics-docker/tree/main/v1.1/n4_areaDetector#readmemd standard], [https://github.com/prjemian/epics-docker/tree/main/v1.1/n6_custom_areaDetector#readmemd custom]&lt;br /&gt;
===Virtual Machines===&lt;br /&gt;
* [https://github.com/BCDA-APS/epics-bluesky-vm/blob/main/install_vm.md APS Bluesky 101 training VM image.]&lt;br /&gt;
&lt;br /&gt;
==Maintaining Documentation==&lt;br /&gt;
* [https://bctwg.readthedocs.io/en/latest/index.html ReadTheDocs tutorial and example site]&lt;br /&gt;
&lt;br /&gt;
==APS ESAF &amp;amp; Proposal - Read-only interface==&lt;br /&gt;
* [https://bcda-aps.github.io/apsbss/ apsbss - Read-only interface to information from APS Proposal and ESAF (experiment safety approval form) databases.]&lt;br /&gt;
&lt;br /&gt;
==Bluesky==&lt;br /&gt;
* [https://blueskyproject.io Bluesky home page]&lt;br /&gt;
* [https://try.nsls2.bnl.gov Try Bluesky in a web browser (from NSLS-II)]&lt;br /&gt;
* [https://bcda-aps.github.io/apstools apstools - Various Python tools for use with Bluesky at the APS.], [https://bcda-aps.github.io/apstools/examples/index.html Guides, How-Tos, and other examples.] [https://github.com/BCDA-APS/bluesky_training/blob/main/APS_Bluesky_101.md APS Bluesky 101 (from 2021).]&lt;br /&gt;
* [https://blueskyproject.io/hklpy/ hklpy: Bluesky's diffractometer support], [https://blueskyproject.io/hklpy/examples/index.html Diffractometer examples.]&lt;br /&gt;
* [https://github.com/BCDA-APS/bluesky_training Bluesky training for APS users]&lt;br /&gt;
* [https://github.com/BCDA-APS/bluesky_training/tree/main/bluesky Template for new instrument description. (Includes configuration for IPython console, Jupyter notebook, and bluesky-queueserver.]&lt;br /&gt;
* [https://github.com/BCDA-APS/use_bluesky#use_bluesky Installation Steps for APS users]&lt;br /&gt;
* [https://blueskyproject.io/bluesky-queueserver/ queueserver - Server for queueing plans.], [https://blueskyproject.io/bluesky-queueserver-api/ API documentation]&lt;br /&gt;
* [https://blueskyproject.io/tiled/ tiled - Data server for databroker and directories with data files.], [https://github.com/BCDA-APS/tiled-template Template for creating a local tiled data server at APS.]&lt;br /&gt;
* [https://slaclab.github.io/pydm/ PyDM - Python Display Manager]&lt;br /&gt;
* [https://github.com/BCDA-APS/adl2pydm adl2pydm - Convert MEDM's .adl files to PyDM's .ui format.]&lt;br /&gt;
&lt;br /&gt;
==Python support==&lt;br /&gt;
===Channel Access===&lt;br /&gt;
* [https://pyepics.github.io/pyepics/ PyEpics - Python interface for Channel Access based on libca and libCom.]&lt;br /&gt;
* [https://caproto.github.io/caproto/v0.8.1/ caproto - Python interface for Channel Access in pure Python.]&lt;br /&gt;
===PV Access===&lt;br /&gt;
* [https://mdavidsaver.github.io/p4p/ p4p - Python interface for PV Access]&lt;br /&gt;
* [https://github.com/epics-base/pvaPy pvapy - Python interface for PV Access, also provides CA interface]&lt;br /&gt;
===General===&lt;br /&gt;
* [https://bcdamenu.readthedocs.io/ bcdamenu - GUI menu to beam line software, such as synoptic display.]&lt;br /&gt;
* [https://github.com/EPICS-synApps/support/tree/master/utils/mdaPythonUtils mdaPythonUtils - Read .mda data files into Python.]&lt;br /&gt;
* [https://github.com/prjemian/pvMail PvMail - Watch an EPICS PV. Send email when it changes from 0 to 1.]&lt;br /&gt;
* [https://github.com/BCDA-APS/pvview pvView - Display one or more EPICS PVs in a PyDM GUI window as a table.]&lt;br /&gt;
* [https://github.com/BCDA-APS/pvWebMonitor pvWebMonitor - Post EPICS PVs to read-only (static) web site.]&lt;br /&gt;
* [https://prjemian.github.io/punx/ punx - Python Utilities for NeXus HDF5 files: validation, structure, hierarchy.]&lt;br /&gt;
* [https://prjemian.github.io/pyRestTable/ pyRestTable - Format a nice table in reST (reStructuredText) from Python.]&lt;br /&gt;
* [https://prjemian.github.io/pysumreg/ pysumreg - Statistics of list of (x,y) pairs from calculator-style summation registers.]&lt;br /&gt;
* [https://github.com/prjemian/spec2nexus/ spec2nexus - Read SPEC data files into Python, write NeXus data file.]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=291</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=291"/>
		<updated>2023-03-15T06:55:43Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets can arrive out-of-order, which may increase CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate TCP ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple TCP/UDP ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=290</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=290"/>
		<updated>2023-03-15T06:55:26Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Maximum throughput (one-to-one) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets can arrive out-of-order, which may increase CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate TCP ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=289</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=289"/>
		<updated>2023-03-15T06:55:08Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Maximum throughput (one-to-one) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets can arrive out-of-order, which may increase CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=288</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=288"/>
		<updated>2023-03-15T06:54:48Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Maximum throughput (one-to-one) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets may arrive out-of-order, which increases CPU load on the receiver or causes retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=287</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=287"/>
		<updated>2023-03-15T06:16:10Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Maximum throughput (one-to-one) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets may arrive out-of-order, which increases CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=286</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=286"/>
		<updated>2023-03-15T06:14:21Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Bonding modes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces (duplicated).&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets may arrive out-of-order, which increases CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs on different subnets, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=285</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=285"/>
		<updated>2023-03-15T05:11:06Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Testing and troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets may arrive out-of-order, which increases CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs on different subnets, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=284</id>
		<title>Linux network teaming</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Linux_network_teaming&amp;diff=284"/>
		<updated>2023-03-15T05:10:46Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Created page with &amp;quot;==Introduction== Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Network teaming, or bonding, involves combining multiple physical network interfaces (NICs) into one virtual interface for increased reliability or throughput. It is well-supported on the APS network. However, there are many possible pitfalls and areas of confusion when configuring bonded interfaces.&lt;br /&gt;
&lt;br /&gt;
==Streams or flows==&lt;br /&gt;
The aggregated bandwidth of a bonded link is not​ the same as the bandwidth available to a single &amp;quot;stream&amp;quot; or &amp;quot;flow&amp;quot; of network packets. What defines a single stream? Here are the usual possibilities (see the &amp;lt;code&amp;gt;runner.tx_hash&amp;lt;/code&amp;gt; setting in Linux teamd):&lt;br /&gt;
&lt;br /&gt;
* Layer 2 only: Any network packet with the same source and destination MAC is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 3: Any network packet with the same source and destination IP is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
* Layer 4: Any network packet with the same source and destination IP and source and destination TCP/UDP port​​ is part of the same &amp;quot;stream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Depending on how streams are distributed among the available interfaces, the aggregated transmission bandwidth for all streams may be the same as, or different to, the transmission bandwidth available for a single stream.&lt;br /&gt;
&lt;br /&gt;
==Bonding modes==&lt;br /&gt;
The bonding mode decides how each stream is handled. Using the teamd​ terminology (see &amp;lt;code&amp;gt;runner.name&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
; broadcast : every packet of every stream is sent over all bonded interfaces.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; roundrobin : the packets of every stream are cycled between interfaces in order. Packet 1 -&amp;gt; interface 1, Packet 2 -&amp;gt;  interface 2, Packet 3 -&amp;gt; interface 1, etc.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single-stream bandwidth = a bit less than the sum of all links (60-80% perhaps), because packets will sometimes arrive out-of-order.&lt;br /&gt;
; activebackup : the packets of every stream are sent over the designated &amp;quot;active&amp;quot; connection, if that fails they are sent over the next backup.&lt;br /&gt;
: aggregate bandwidth = single link bandwidth. single-stream bandwidth = single link bandwidth.&lt;br /&gt;
; loadbalance : the transmitting computer hashes the stream info (Layer 2, 3, or 4 described above) modulo the number of interfaces, and uses that to assign it to an interface. For example if ''loadbalance+Layer 2'' is selected, any packet which satisfies &amp;lt;code&amp;gt;hash(src MAC, dest MAC) == 1&amp;lt;/code&amp;gt; will be sent over interface 1.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth,​​ because a single stream will always hash to transmit over the same interface.&lt;br /&gt;
; 802.3ad / LACP : allows the transmitter to automatically notify the switch/gateway that the physical ports are bonded. After that all of the behavior is the same as loadbalance above.&lt;br /&gt;
: aggregate bandwidth = sum of all links. single stream bandwidth = single link bandwidth​, as for ''loadbalance''.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Maximum throughput (one-to-one) ===&lt;br /&gt;
Consider a simple configuration where we are trying to get maximum throughput from a single detector PC to network storage. The connection from the detector PC is the bottleneck so we add an extra interface card.&lt;br /&gt;
How should we configure the two available interfaces?&lt;br /&gt;
&lt;br /&gt;
[[File:Bonding_network_diagram.png|thumb|center|800px]]&lt;br /&gt;
&lt;br /&gt;
There are only two ways​ to get more transmission bandwidth over the bonded link than a single link (10 Gb):&lt;br /&gt;
&lt;br /&gt;
* Use '''roundrobin''' mode. No application support required. Packets may arrive out-of-order, which increases CPU load on the receiver or cause retransmissions.&lt;br /&gt;
* Use '''loadbalance mode and multiple streams which hash to different interfaces'''. Requires application support to generate multiple streams and an appropriate stream definition/hashing algorithm chosen. For example, if Layer 4 hashing is chosen, the application can transmit on two separate ports which hash to interface 1 and 2. The receiving application then must reconstruct the data into a single data stream, if required.&lt;br /&gt;
&lt;br /&gt;
Another option is to avoid network teaming entirely, and configure each interface with separate IPs on different subnets, guaranteeing both transmissions can happen in parallel.&lt;br /&gt;
&lt;br /&gt;
==Testing and troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iperf3&amp;lt;/code&amp;gt; is a common tool used to test network bandwidth between two points. Run &amp;lt;code&amp;gt;iperf3 -s&amp;lt;/code&amp;gt; on one computer, and &amp;lt;code&amp;gt;iperf3 -c {hostname}&amp;lt;/code&amp;gt; on another. By default, iperf3 will only create a single network stream. Adding the &amp;lt;code&amp;gt;--parallel {n}&amp;lt;/code&amp;gt; flag will cause the iperf3 client to use multiple ports to connect to the server and so, if ''loadbalance+Layer 4'' hashing is chosen on the bonded interfaces, allow for multi-stream testing with respect to the bonded network interfaces. Note this still runs iperf3 within a single thread and on a single CPU core.&lt;br /&gt;
&lt;br /&gt;
Alternatively, start up entirely separate iperf3 server instances, listening on different ports, and run several clients in parallel. This can allow the use of multiple network streams (assuming Layer 4 hashing) and CPU cores.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [https://www.kernel.org/doc/html/latest/networking/bonding.html Linux Ethernet Bonding Driver HOWTO]&lt;br /&gt;
* [https://manpages.ubuntu.com/manpages/jammy/man5/teamd.conf.5.html man(5) teamd.conf]&lt;br /&gt;
* [https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=File:Bonding_network_diagram.png&amp;diff=283</id>
		<title>File:Bonding network diagram.png</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=File:Bonding_network_diagram.png&amp;diff=283"/>
		<updated>2023-03-15T04:53:34Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Tguruswamy uploaded a new version of File:Bonding network diagram.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Simple diagram used in explanation of network teaming/bonding&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=File:Bonding_network_diagram.png&amp;diff=282</id>
		<title>File:Bonding network diagram.png</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=File:Bonding_network_diagram.png&amp;diff=282"/>
		<updated>2023-03-15T04:49:43Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Simple diagram used in explanation of network teaming/bonding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Simple diagram used in explanation of network teaming/bonding&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=281</id>
		<title>Beamline Controls</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=281"/>
		<updated>2023-03-15T04:15:26Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* Beamline Controls Documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;WIKI for the APS Beamline Controls Community, maintained by the Beamline Controls Technical Working Group.&amp;lt;br /&amp;gt;&lt;br /&gt;
This wiki exists to collect the output of the working group, including documentation on beamline controls software and hardware useful for APS beamline scientists and resident users.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Documentation===&lt;br /&gt;
&lt;br /&gt;
* [[Controls Software Documentation]]&lt;br /&gt;
* [[EPICS_for_Dummies|EPICS 101]]&lt;br /&gt;
* [[Hardware and IT Configuration]]&lt;br /&gt;
&lt;br /&gt;
===Practical Beamline Controls Training (2023)===&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Basics|Session 1: IOC Basics]]&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Deployment_.26_Troubleshooting|Session 2: IOC Deployment &amp;amp; Troubleshooting]]&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Technical Working Group information===&lt;br /&gt;
&lt;br /&gt;
The BC Technical Working (BCTWG) group meets monthly to review and gather feedback on possible changes in either the way BC delivers support or the technologies that BC supports. The BCTWG comprises the BC group plus interested stakeholders from XSD. In a nutshell, the main goal of the BCTWG is to improve communication between BC and its customers on topics of mutual interest.&lt;br /&gt;
&lt;br /&gt;
* Box folder with slides and meeting notes (ANL only): [https://anl.box.com/s/chcn7xauil93inay8ipinbxtcckc9k9f]&lt;br /&gt;
&lt;br /&gt;
* Current chairs:&lt;br /&gt;
** Kevin Peterson (XSD-BC)&lt;br /&gt;
** Tejas Guruswamy (XSD-DET)&lt;br /&gt;
** Andrew Chuang (XSD-MPE)&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Hardware_and_IT_Configuration&amp;diff=280</id>
		<title>Hardware and IT Configuration</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Hardware_and_IT_Configuration&amp;diff=280"/>
		<updated>2023-03-15T03:49:54Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Created page with &amp;quot;This page exists to collect links and resources on controls hardware and related topics useful to beamline scientists. Examples might include information on certain control eq...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page exists to collect links and resources on controls hardware and related topics useful to beamline scientists. Examples might include information on certain control equipment (detectors, motors, FPGAs, etc.), correct setup and use of networking or storage IT infrastructure (without reference to specific ANL information), and low-level configuration of operating systems and device drivers for effective operation.&lt;br /&gt;
&lt;br /&gt;
==Controls Hardware==&lt;br /&gt;
* [https://wiki.aps.anl.gov/bts/index.php?title=Main_Page Detector Pool wiki] (APS internal)&lt;br /&gt;
* [https://wiki.aps.anl.gov/bcda/index.php?title=Category:RECOMMENDED Beamline Controls group recommended hardware] (APS internal)&lt;br /&gt;
&lt;br /&gt;
==IT==&lt;br /&gt;
* [[Linux network teaming]] -- aka bonding, combining multiple network interfaces for increased network bandwidth&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=279</id>
		<title>Beamline Controls</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Beamline_Controls&amp;diff=279"/>
		<updated>2023-03-15T03:39:16Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;WIKI for the APS Beamline Controls Community, maintained by the Beamline Controls Technical Working Group.&amp;lt;br /&amp;gt;&lt;br /&gt;
This wiki exists to collect the output of the working group, including documentation on beamline controls software and hardware useful for APS beamline scientists and resident users.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Documentation===&lt;br /&gt;
&lt;br /&gt;
* [[Controls Software Documentation]]&lt;br /&gt;
* [[EPICS_for_Dummies|EPICS 101]]&lt;br /&gt;
* [[Hardware Configuration]]&lt;br /&gt;
&lt;br /&gt;
===Practical Beamline Controls Training (2023)===&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Basics|Session 1: IOC Basics]]&lt;br /&gt;
&lt;br /&gt;
[[Practical_Beamline_Controls_Training#IOC_Deployment_.26_Troubleshooting|Session 2: IOC Deployment &amp;amp; Troubleshooting]]&lt;br /&gt;
&lt;br /&gt;
===Beamline Controls Technical Working Group information===&lt;br /&gt;
&lt;br /&gt;
The BC Technical Working (BCTWG) group meets monthly to review and gather feedback on possible changes in either the way BC delivers support or the technologies that BC supports. The BCTWG comprises the BC group plus interested stakeholders from XSD. In a nutshell, the main goal of the BCTWG is to improve communication between BC and its customers on topics of mutual interest.&lt;br /&gt;
&lt;br /&gt;
* Box folder with slides and meeting notes (ANL only): [https://anl.box.com/s/chcn7xauil93inay8ipinbxtcckc9k9f]&lt;br /&gt;
&lt;br /&gt;
* Current chairs:&lt;br /&gt;
** Kevin Peterson (XSD-BC)&lt;br /&gt;
** Tejas Guruswamy (XSD-DET)&lt;br /&gt;
** Andrew Chuang (XSD-MPE)&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Documentation&amp;diff=278</id>
		<title>Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Documentation&amp;diff=278"/>
		<updated>2023-03-15T03:37:30Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Tguruswamy moved page Documentation to Controls Software Documentation: make room for hardware page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Controls Software Documentation]]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=277</id>
		<title>Controls Software Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=277"/>
		<updated>2023-03-15T03:37:29Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Tguruswamy moved page Documentation to Controls Software Documentation: make room for hardware page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page exists to collect links to documentation about the instrument control system EPICS, its modules and related libraries (synApps, areaDetector), as used at the Advanced Photon Source.&lt;br /&gt;
&lt;br /&gt;
Documentation referenced should be appropriate for beamline scientists, as opposed to only EPICS developers.&lt;br /&gt;
New deployments should prefer EPICSv7, the latest release series.&lt;br /&gt;
&lt;br /&gt;
See also the extensive [https://epics-controls.org/resources-and-support/documents/training/ resources from past EPICS Collaboration meetings].&lt;br /&gt;
&lt;br /&gt;
==EPICS Base==&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Intro.html Intro to EPICS]&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html EPICS Database Concepts]&lt;br /&gt;
* [https://docs.epics-controls.org/projects/how-tos/en/latest/getting-started/installation.html EPICS Base Getting Started (official)]&lt;br /&gt;
* [https://cmd-response.readthedocs.io/en/latest/epics/rpi_epics.html Installing EPICS on RaspberryPi]&lt;br /&gt;
&lt;br /&gt;
==synApps (aka EPICS Support)==&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps_docs_all.html synApps Collected Documentation]&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps.html synApps deployment instructions, including use of xxx template ioc]&lt;br /&gt;
&lt;br /&gt;
==areaDetector==&lt;br /&gt;
* [https://areadetector.github.io/master/index.html areaDetector Official Documentation]&lt;br /&gt;
&lt;br /&gt;
==Deploying, troubleshooting, and maintaining IOCs==&lt;br /&gt;
* [[Troubleshooting EPICS IOCs]]&lt;br /&gt;
* [https://docs2bm.readthedocs.io/en/latest/source/ops/item_000_0.html simDetector Install directions (2BM)]&lt;br /&gt;
* [https://epics-modules.github.io/xxx/overview.html The Basics of an IOC (XXX documentation)]&lt;br /&gt;
* [https://gist.github.com/keenanlang/e768774cbd0a367b96281939b8a2c9ba Creation of an IOC using mkioc]&lt;br /&gt;
* [https://wiki.aps.anl.gov/bcda/index.php/Category:TUTORIAL BCDA Tutorials (APS Internal)]&lt;br /&gt;
&lt;br /&gt;
==Pre-built IOCs==&lt;br /&gt;
===Docker images===&lt;br /&gt;
* EPICS Base 7.0.5, synApps 6.2: [https://github.com/prjemian/epics-docker/tree/main/v1.1/n3_synApps#readmemd standard xxx], [https://github.com/prjemian/epics-docker/tree/main/v1.1/n5_custom_synApps#readmemd customized]&lt;br /&gt;
* EPICS Base 7.0.5, synApps 6.2, area detector 3.10: [https://github.com/prjemian/epics-docker/tree/main/v1.1/n4_areaDetector#readmemd standard], [https://github.com/prjemian/epics-docker/tree/main/v1.1/n6_custom_areaDetector#readmemd custom]&lt;br /&gt;
===Virtual Machines===&lt;br /&gt;
* [https://github.com/BCDA-APS/epics-bluesky-vm/blob/main/install_vm.md APS Bluesky 101 training VM image.]&lt;br /&gt;
&lt;br /&gt;
==Maintaining Documentation==&lt;br /&gt;
* [https://bctwg.readthedocs.io/en/latest/index.html ReadTheDocs tutorial and example site]&lt;br /&gt;
&lt;br /&gt;
==APS ESAF &amp;amp; Proposal - Read-only interface==&lt;br /&gt;
* [https://bcda-aps.github.io/apsbss/ apsbss - Read-only interface to information from APS Proposal and ESAF (experiment safety approval form) databases.]&lt;br /&gt;
&lt;br /&gt;
==Bluesky==&lt;br /&gt;
* [https://blueskyproject.io Bluesky home page]&lt;br /&gt;
* [https://try.nsls2.bnl.gov Try Bluesky in a web browser (from NSLS-II)]&lt;br /&gt;
* [https://bcda-aps.github.io/apstools apstools - Various Python tools for use with Bluesky at the APS.], [https://bcda-aps.github.io/apstools/examples/index.html Guides, How-Tos, and other examples.] [https://github.com/BCDA-APS/bluesky_training/blob/main/APS_Bluesky_101.md APS Bluesky 101 (from 2021).]&lt;br /&gt;
* [https://blueskyproject.io/hklpy/ hklpy: Bluesky's diffractometer support], [https://blueskyproject.io/hklpy/examples/index.html Diffractometer examples.]&lt;br /&gt;
* [https://github.com/BCDA-APS/bluesky_training Bluesky training for APS users]&lt;br /&gt;
* [https://github.com/BCDA-APS/bluesky_training/tree/main/bluesky Template for new instrument description. (Includes configuration for IPython console, Jupyter notebook, and bluesky-queueserver.]&lt;br /&gt;
* [https://github.com/BCDA-APS/use_bluesky#use_bluesky Installation Steps for APS users]&lt;br /&gt;
* [https://blueskyproject.io/bluesky-queueserver/ queueserver - Server for queueing plans.], [https://blueskyproject.io/bluesky-queueserver-api/ API documentation]&lt;br /&gt;
* [https://blueskyproject.io/tiled/ tiled - Data server for databroker and directories with data files.], [https://github.com/BCDA-APS/tiled-template Template for creating a local tiled data server at APS.]&lt;br /&gt;
* [https://slaclab.github.io/pydm/ PyDM - Python Display Manager]&lt;br /&gt;
* [https://github.com/BCDA-APS/adl2pydm adl2pydm - Convert MEDM's .adl files to PyDM's .ui format.]&lt;br /&gt;
&lt;br /&gt;
==Python support==&lt;br /&gt;
===Channel Access===&lt;br /&gt;
* [https://pyepics.github.io/pyepics/ PyEpics - Python interface for Channel Access based on libca and libCom.]&lt;br /&gt;
* [https://caproto.github.io/caproto/v0.8.1/ caproto - Python interface for Channel Access in pure Python.]&lt;br /&gt;
===PV Access===&lt;br /&gt;
* [https://mdavidsaver.github.io/p4p/ p4p - Python interface for PV Access]&lt;br /&gt;
* [https://github.com/epics-base/pvaPy pvapy - Python interface for PV Access, also provides CA interface]&lt;br /&gt;
===General===&lt;br /&gt;
* [https://bcdamenu.readthedocs.io/ bcdamenu - GUI menu to beam line software, such as synoptic display.]&lt;br /&gt;
* [https://github.com/EPICS-synApps/support/tree/master/utils/mdaPythonUtils mdaPythonUtils - Read .mda data files into Python.]&lt;br /&gt;
* [https://github.com/prjemian/pvMail PvMail - Watch an EPICS PV. Send email when it changes from 0 to 1.]&lt;br /&gt;
* [https://github.com/BCDA-APS/pvview pvView - Display one or more EPICS PVs in a PyDM GUI window as a table.]&lt;br /&gt;
* [https://github.com/BCDA-APS/pvWebMonitor pvWebMonitor - Post EPICS PVs to read-only (static) web site.]&lt;br /&gt;
* [https://prjemian.github.io/punx/ punx - Python Utilities for NeXus HDF5 files: validation, structure, hierarchy.]&lt;br /&gt;
* [https://prjemian.github.io/pyRestTable/ pyRestTable - Format a nice table in reST (reStructuredText) from Python.]&lt;br /&gt;
* [https://prjemian.github.io/pysumreg/ pysumreg - Statistics of list of (x,y) pairs from calculator-style summation registers.]&lt;br /&gt;
* [https://github.com/prjemian/spec2nexus/ spec2nexus - Read SPEC data files into Python, write NeXus data file.]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_for_Dummies&amp;diff=273</id>
		<title>EPICS for Dummies</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_for_Dummies&amp;diff=273"/>
		<updated>2023-03-08T02:25:50Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* What is an IOC? */ resize image&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is EPICS? ==&lt;br /&gt;
&lt;br /&gt;
EPICS (Experimental Physics and Industrial Control System) is a distributed control system, which means that the IOC (software) can run on a different computer as the user interfaces.&lt;br /&gt;
&lt;br /&gt;
The next 5 sections are dedicated to the definition of basic EPICS components (IOC, PV, record, database, &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;add devices?&amp;lt;/span&amp;gt;). To create your own EPICS support, you can skip directly to [[#How does one create an IOC?]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is an IOC? ==&lt;br /&gt;
&lt;br /&gt;
[[File:EPICS_basics_PV_diagram.png|right|thumb|600px]]&lt;br /&gt;
&lt;br /&gt;
IOC (Input/Output Controller) is a piece of software running on a computer:&lt;br /&gt;
* loads '''databases'''&lt;br /&gt;
* serves something called '''process variables''' (PVs) that you can read and write to&lt;br /&gt;
* used to run on VMEs, but nowadays it runs on anything. &lt;br /&gt;
* usually talks to hardware, but that isn’t a requirement.&lt;br /&gt;
&lt;br /&gt;
IOCs are started with startup scripts. Those scripts tell the IOC what database files to load and where those files are. When the IOC is told to load a database, what it is doing is parsing that database file, identifying the records that are contained within, and then generating the actual epics PVs that a user will interact with.&lt;br /&gt;
&lt;br /&gt;
'''Records''' and '''databases''' (lists of records) are configuration files describing the initial setup for '''PVs''', the '''IOC''' is the software that manages the behavior of PVs and communication to get/set their values.&lt;br /&gt;
&lt;br /&gt;
== What is a PV? ==&lt;br /&gt;
&lt;br /&gt;
PV (Process Variable) is a the field from a record: &lt;br /&gt;
 ''PV = record_name + . + field_name''&lt;br /&gt;
&lt;br /&gt;
Most of the interactive parts of user displays have PVs associated with them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a record? ==&lt;br /&gt;
&lt;br /&gt;
Records are the building blocks of EPICS:&lt;br /&gt;
* There is a lot of different types of record, and each type is designed to perform a specific function &lt;br /&gt;
* Records are customizable via fields that allow users to configure how they behave and monitor their state (see [[#More about record fields]] to know how to learn about record fields)&lt;br /&gt;
* Records do nothing until they are processed (see [[#SCAN, PROC &amp;amp; FLNK fields]])&lt;br /&gt;
* Records vary significantly in complexity (see [[#More about records]])&lt;br /&gt;
* It is rare for new records to be created, now that ''asyn'' device support exists &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;add link to asyn?&amp;lt;/span&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Where do records come from? ===&lt;br /&gt;
&lt;br /&gt;
Typically, records at the APS comes from either:&lt;br /&gt;
* '''[https://epics.anl.gov/base/index.php EPICS base]''': main core of EPICS&lt;br /&gt;
* '''[https://www.aps.anl.gov/BCDA/synApps synApps]''': a collection of EPICS modules that are commonly used at the APS&lt;br /&gt;
A module is similar to a python package: it is an already written set of databases and associated behavior you can load into your IOC to do certain things, for example talk to specific hardware. An IOC can link to several modules.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ Records in synApps modules &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Module !! Records !! Module !! Records&lt;br /&gt;
|-&lt;br /&gt;
| alive || alive || motor || motor&lt;br /&gt;
|-&lt;br /&gt;
| asyn || asyn || optics || table&lt;br /&gt;
|-&lt;br /&gt;
| busy || busy || scaler || scaler&lt;br /&gt;
|-&lt;br /&gt;
| calc || acalcout, scalcout, sseq, swait, transform || sscan || sscan&lt;br /&gt;
|-&lt;br /&gt;
| camac || camac || std || epid, timestamp, throttle&lt;br /&gt;
|-&lt;br /&gt;
| lua || luascript || vac || digitel, vs&lt;br /&gt;
|-&lt;br /&gt;
| mca || mca || vme || vme&lt;br /&gt;
|-&lt;br /&gt;
| allenBradley || ab1771IFE, ab1771N, ab1771IX, ...|| allenBradley || ..., ab1791, abDcm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If a record isn't listed here, it probably comes from EPICS base. &lt;br /&gt;
The advantage to using synApps over a collection of modules one assembles on their own is that some amount of BCDA testing has been done.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What is a record field? ===&lt;br /&gt;
&lt;br /&gt;
Record fields are controllable or informative properties of a record.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Noteworthy fields====&lt;br /&gt;
&lt;br /&gt;
*'''VAL''' - the default field (used if no field is specified in the vast majority of cases)&lt;br /&gt;
*'''SCAN''' - determines when a record processes&lt;br /&gt;
*'''NAME''' - the record name (helpful if records are aliased)&lt;br /&gt;
*'''DESC''' - record description&lt;br /&gt;
*'''RTYP''' - the record type&lt;br /&gt;
*'''DTYP''' - the device support type (not meaningful for all record types)&lt;br /&gt;
*'''DISP''' - disable puts (ca = channel access &amp;amp; pva = pv access) from outside the IOC (when non-zero); e.g. disable a motor from the motorx_all screen&lt;br /&gt;
*'''DISV/DISA/SDIS''' - disable record processing internally &lt;br /&gt;
**Record processing is disabled when '''DISA''' equals '''DISV''' (e.g. uses SDIS field to read in a value/mode, which will disable some control if a certain mode is active)&lt;br /&gt;
**'''DISA''' is set to the value of the PV in the '''SDIS''' field, if it isn't empty&lt;br /&gt;
*'''TPRO''' - trace processing: when set to 1 prints out all the records that get processed after the record is processed; used only for troubleshooting&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: some of the fields of a record are actually record attributes (they return the same value for all instances of the record type; see [https://epics.anl.gov/base/R3-16/2-docs/AppDevGuide/DatabaseDefinition.html#x7-2630006.6 https://epics.anl.gov/])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== SCAN, PROC &amp;amp; FLNK fields ====&lt;br /&gt;
&lt;br /&gt;
Records do nothing until they are processed. Records can be processed multiple ways:&lt;br /&gt;
* &amp;lt;u&amp;gt;Manually&amp;lt;/u&amp;gt;:&lt;br /&gt;
** Write 1 (or any non-zero value) to a record’s '''PROC''' field&lt;br /&gt;
**Forward link ('''FLNK''') from another record&lt;br /&gt;
* &amp;lt;u&amp;gt;Periodically&amp;lt;/u&amp;gt; by setting the '''SCAN''' field to something other than &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ SCAN field options &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Index !! Option !! Index !! Option&lt;br /&gt;
|-&lt;br /&gt;
| 0 || &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;   || 5 || &amp;lt;code&amp;gt;2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt;     || 6 || &amp;lt;code&amp;gt;1 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2 || &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt;  ||7 || &amp;lt;code&amp;gt;0.5 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 3 || &amp;lt;code&amp;gt;10 second&amp;lt;/code&amp;gt;  ||8 || &amp;lt;code&amp;gt;0.2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4 || &amp;lt;code&amp;gt;5 second&amp;lt;/code&amp;gt;  ||9 || &amp;lt;code&amp;gt;0.1 second&amp;lt;/code&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* If a record’s SCAN field is not specified in a database, it defaults to &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.  &lt;br /&gt;
* The '''SCAN''' field is common to ''all'' record types and the options can be selected by index instead of by string.&lt;br /&gt;
* &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt; processes a record when the driver gets a new value, but is device/driver dependent and isn’t guaranteed to work&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Record link types ===&lt;br /&gt;
&lt;br /&gt;
Much of the power of EPICS comes from the ability to link EPICS records together.&lt;br /&gt;
There are two link implementations: standard and dynamic.  &lt;br /&gt;
* Dynamic links (pink) are found on ''userCalc'' ('''swait''' records) and ''scan'' ('''sscan''' records) screens; this type of link accept only a PV name. THe role of the process command (see below) is taken in a separate field.   &lt;br /&gt;
* Standard links (purple) are found everywhere else.&lt;br /&gt;
''inlinkHelp'' and ''outlinkHelp'' are accessible from userTransform screens and scaler screens (for the later only).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Input Links ====&lt;br /&gt;
&lt;br /&gt;
Input links read a value from another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an input link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just read the value; don't process the target record (i.e. read a potentially stale value); this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Process the target record and then read a value from it.&lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Read a value without causing processing to occur.&lt;br /&gt;
* &amp;lt;code&amp;gt;CP&amp;lt;/code&amp;gt; - Process linking record every time the target record processes.&lt;br /&gt;
* &amp;lt;code&amp;gt;CPP&amp;lt;/code&amp;gt; - Same as CP, but linking record process only if its SCAN field has the value &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: ''inlinkHelp'' is accessible from userTransform screens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Output Links ====&lt;br /&gt;
&lt;br /&gt;
Output links write a value to another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an output link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just write a value; don't process the target record; this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Write a value and then process the target record. To be use if you want EPICS to trace processing (&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;= wait for completion?&amp;lt;/span&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Write a value; let the target record decide whether or not to process (as it would if you typed the value by hand); if the processing does occur, EPICS will not trace it. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: &lt;br /&gt;
* The default link process command, &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;, is '''almost never the desired behavior''' for output links. Change &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; immediately and revert if problems are discovered.&lt;br /&gt;
* If the target PV is itself a link field, you must specify the command &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt;; if you want to wait for completion in this case, you must use either the '''sseq''' or the '''sCalcout''' record, select &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; and set the link's '''WAIT''' field to &amp;lt;code&amp;gt;Wait&amp;lt;/code&amp;gt;&lt;br /&gt;
* ''outlinkHelp'' is accessible from userTransform and scaler screens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Forward Links ====&lt;br /&gt;
&lt;br /&gt;
Forward link look like output links; they are purple on user displays, but they don't auto-populate with process &amp;amp; alarm commands. &lt;br /&gt;
Forward link causes the linked record to process when the record containing the forward link is processed&lt;br /&gt;
* Linked record is in the same IOC ('''PROC''' field for linked record is optional):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
* Linked record is in a different IOC ('''PROC''' field for linked record is required):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* Forwarding-linking records in the same IOC by only specifying the record name is an exception to the &amp;quot;'''VAL''' ''is the default field''&amp;quot; rule.&lt;br /&gt;
* When omitting the '''PROC''' field of a linked record in a different IOC, nothing will happen but you won't get any error message.&lt;br /&gt;
* Always specify the '''PROC''' field to avoid problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More about records ===&lt;br /&gt;
&lt;br /&gt;
* Records vary significantly in complexity; one way to classify them would be (*):&lt;br /&gt;
** Simple records are associated with individual data types&lt;br /&gt;
*::;bi, bo, mbbi, mbbo, longin, longout, ai, ao, stringin, stringout, waveform&lt;br /&gt;
** Intermediate records often perform calculations or link multiple records&lt;br /&gt;
*::;calcout, scalcout, acalcout, swait, transform, fanout, dfanout&lt;br /&gt;
** Complex records are associated with devices or higher-level functionality&lt;br /&gt;
*::;motor, scaler, mca, sscan, table, digitel, vs&lt;br /&gt;
** Flexible records allow custom functionality to be implemented&lt;br /&gt;
*::;sub, aSub, luascript&lt;br /&gt;
(*) this is not an official classification, nor an exhaustive list of records.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* areaDetector databases are composed of mostly simple record.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More about record fields ===&lt;br /&gt;
&lt;br /&gt;
To find documentation for a specific field you need to know/find answers to the following questions:&lt;br /&gt;
* Is the field common to all or input/output record types?  &lt;br /&gt;
* If not, does the record come from EPICS base or a different EPICS module (synApps)?&lt;br /&gt;
** The [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation] is the best place to find information about record types that come from EPICS base. &amp;lt;br&amp;gt;Field documentation appears in multiple locations:&lt;br /&gt;
*** Fields common to all record types&lt;br /&gt;
*** Fields common to input record types&lt;br /&gt;
*** Fields common to output record types&lt;br /&gt;
*** Record-specific documentation&lt;br /&gt;
** synApps record reference documentation&lt;br /&gt;
*** In each module's documentation directory&lt;br /&gt;
**** [https://github.com/epics-modules https://github.com/epics-modules]&lt;br /&gt;
**** &amp;lt;code&amp;gt;/APSshare/epics/synApps_X_Y/support&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a databases? ==&lt;br /&gt;
&lt;br /&gt;
A database is just a text file with a '''.db''' (or '''.template''') extension containing a collection of records that are related. &lt;br /&gt;
&lt;br /&gt;
Databases are generalized with macros to allow multiple instances to be loaded (e.g. $(P)):&lt;br /&gt;
* Macros are variables containing strings to be substituted when the database is loaded.&lt;br /&gt;
* Macros without default values are required to load the database; there is no easy way to figure out what those are for a given database other than looking at the file itself.&lt;br /&gt;
* Macros required by the database should match the macros required by associated screens &amp;amp; autosave (.req) files.&lt;br /&gt;
* The P (prefix) macro usually includes a colon (:), which is the standard separator used in PV names.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How are databases loaded? ===&lt;br /&gt;
&lt;br /&gt;
There are 2 ways to load databases which are strictly equivalent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== dbLoadRecords ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam1,PORT=serial1,A=01&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam2,PORT=serial1,A=02&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== dbLoadTemplate ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadTemplate(&amp;quot;substitutions/ADAM_4018.substitutions&amp;quot;,&amp;quot;P=kmp:&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ADAM_4018.substitutions:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;file &amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;&lt;br /&gt;
 {&lt;br /&gt;
 pattern&lt;br /&gt;
 {R,PORT,A}&lt;br /&gt;
 {adam1, serial1,01}&lt;br /&gt;
 {adam2, serial1,02}&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a device? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;What is a device?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How does one create an IOC? ==&lt;br /&gt;
&lt;br /&gt;
There are multiple ways to create an IOC, but no one does it from scratch:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The EPICS base approach ===&lt;br /&gt;
It creates a bare bones IOC but requires more knowledge of the EPICS build system to get started:&lt;br /&gt;
::'''&amp;lt;code&amp;gt;makeBaseApp.pl&amp;lt;/code&amp;gt;'''&lt;br /&gt;
* Must be run multiple times&lt;br /&gt;
* Creates IOC contents in the current directory&lt;br /&gt;
* synApps support needs to be added manually&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The synApps approach ===&lt;br /&gt;
&lt;br /&gt;
It is based on the ''xxx'' module and designed to give you a usable IOC with as little effort as possible:&lt;br /&gt;
::'''&amp;lt;code&amp;gt;mkioc&amp;lt;/code&amp;gt;'''&lt;br /&gt;
 &lt;br /&gt;
* A single command leaves you with an IOC you can build:&lt;br /&gt;
::&amp;lt;code&amp;gt;/APSshare/bin/mkioc -n -f -s 6-2-1 kmp&amp;lt;/code&amp;gt;&lt;br /&gt;
* Creates a top-level IOC directory in the current directory&lt;br /&gt;
* Common synApps support is included by default&lt;br /&gt;
* mkioc will ask you questions if you run it without options&lt;br /&gt;
&lt;br /&gt;
Note: The BCDA convention is to name development IOCs using the developer's initials (here ''kmp'').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IOC Layout ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The IOC layout can be overwhelming and confusing to those who aren’t yet familiar with it. The EPICS build system creates many directories, making it harder to find the important directories.&lt;br /&gt;
Important files are often buried multiple directories down from the top-level. It is helpful to look at subsets of the IOC directory.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;17&amp;quot;; style=&amp;quot;color:blue&amp;quot;|kmp&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|bin&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:red&amp;quot;|rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|configure&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:red&amp;quot;|db&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:red&amp;quot;|dbd&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;4&amp;quot;|iocBoot&lt;br /&gt;
|rowspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:green&amp;quot;|iockmp&lt;br /&gt;
|autosave&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:green&amp;quot;|iocsh&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:blue&amp;quot;| softioc&lt;br /&gt;
| commands&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:green&amp;quot;| substitutions&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;6&amp;quot;|kmpApp&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|Db&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|op&lt;br /&gt;
|adl&lt;br /&gt;
|-&lt;br /&gt;
|ui&lt;br /&gt;
| autoconvert&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|src&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|lib&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:red&amp;quot;|rhel8-x86_64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Build configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: orange&amp;quot;&amp;gt;Orange&amp;lt;/span&amp;gt; folders:&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/configure&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the files that specify which versions of EPICS base and EPICS modules should be should be used when building the IOC.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/kmpApp/Db&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains local databases (and associated autosave files) and protocol files used by the IOC.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/kmpApp/src&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the Makefile that determines all of the software that gets built into the IOC binary. ; local sequence programs and other EPICS support that needs to be compiled go here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Intermediate build directories ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: grey&amp;quot;&amp;gt;Grey&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
The EPICS Build system will generate '''&amp;lt;code&amp;gt;O.&amp;lt;/code&amp;gt;''' files (Common, EPICS HOST and TARGET architectures) in the configure, Db, and src directory.  These directories are not needed after the IOC is built and can be removed with the '''&amp;lt;code&amp;gt;make clean&amp;lt;/code&amp;gt;''' command. If they are not removed, they can be safely ignored.  It is highly unlikely that you will ever need to look at any of the files in them.&lt;br /&gt;
&lt;br /&gt;
=== Build products ===&lt;br /&gt;
&lt;br /&gt;
The EPICS build system creates top level bin, db, dbd, and lib directories (&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;red&amp;lt;/span&amp;gt; folders):  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/bin/rehl8-x86_64&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the architecture-specific IOC binary (or munch file for VxWorks IOCs).  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/db&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains installed database files which may or may not be used, since many IOCs reference the databases in the Db directory instead.  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/dbd&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains a single database definition file to be loaded by the IOC. &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/lib/rehl8-x86_64&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains architecture-specific files for EPICS modules, but should be empty for the IOC.&amp;lt;br&amp;gt;&lt;br /&gt;
The build system creates an envPaths file in the startup directory, which contains the locations of the modules defined in the RELEASE file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Run-time configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;Green&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The iockmp directory is referred to as the ''startup'' directory.  It contains the '''&amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt;''' file, which is the runtime configuration for the IOC &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;what means runtime?&amp;lt;/span&amp;gt;  &lt;br /&gt;
The IOC’s config is often broken into separate '''&amp;lt;code&amp;gt;.iocsh&amp;lt;/code&amp;gt;''' (or '''&amp;lt;code&amp;gt;.cmd&amp;lt;/code&amp;gt;''') files so that support can be more easily commented out and to improve readability.  &lt;br /&gt;
Substitutions and iocsh files usually reside in subdirectories to reduce clutter in the startup directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Start scripts ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Blue&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
The top-level IOC directory contains scripts that start medm/caQtDM.&lt;br /&gt;
The softioc subdirectory of the startup dir contains a bash script which simplifies managing the IOC on Linux.&lt;br /&gt;
Windows IOCs: the startup directory contains batch files to start the IOC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: The startup directory can reside elsewhere.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How does support get into an IOC? ==&lt;br /&gt;
&lt;br /&gt;
[[File:EPICS_basics_linking_diagrams.png|right|thumb|800px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Quick overview ===&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;configure/RELEASE&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** Defines the locations of EPICS base and EPICS modules&lt;br /&gt;
** Often includes other RELEASE files&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmpApp/src/Makefile&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** Specifies which database definitions (dbd) to include&lt;br /&gt;
** Specifies which libraries should be included in the IOC binary&lt;br /&gt;
** Specifies which local code should be included in the IOC binary&lt;br /&gt;
** Libraries will not be included unless an associated dbd file is included&lt;br /&gt;
** The order of the libraries is important (single-pass linker)&lt;br /&gt;
* '''&amp;lt;code&amp;gt;iocBoot/iockmp/st.cmd&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** The primary IOC config file that is sourced when the IOC is started&lt;br /&gt;
** Name can vary slightly based on how the IOC was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Startup script &amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Legacy IOCs often have monolithic '''&amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt;''' files. Newer IOCs source more '''&amp;lt;code&amp;gt;.iocsh&amp;lt;/code&amp;gt;''' files from EPICS modules, which makes it easier to keep an IOC's config up-to-date.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt; envPaths&lt;br /&gt;
 &lt;br /&gt;
 dbLoadDatabase(&amp;quot;../../dbd/iockmpLinux.dbd&amp;quot;)&lt;br /&gt;
 iockmpLinux_registerRecordDeviceDriver(pdbbase)&lt;br /&gt;
 &lt;br /&gt;
 ### Databases are loaded&lt;br /&gt;
 ### Drivers are initialized/configured here&lt;br /&gt;
 &lt;br /&gt;
 iocInit&lt;br /&gt;
 &lt;br /&gt;
 ### Sequence programs &amp;amp; autosave are started here&lt;br /&gt;
 &lt;br /&gt;
 dbl &amp;gt; dbl-all.txt&lt;br /&gt;
 &lt;br /&gt;
 date&lt;br /&gt;
&lt;br /&gt;
We can break it up into 3 functional zones:&lt;br /&gt;
* Zone 1: before '''&amp;lt;code&amp;gt;dbLoadDatabase&amp;lt;/code&amp;gt;'''.  Usually this is where env vars and paths are defined.&lt;br /&gt;
* Zone 2: after '''&amp;lt;code&amp;gt;dbLoadDatabase&amp;lt;/code&amp;gt;''' &amp;amp; before '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  Databases can only be loaded here.&lt;br /&gt;
* Zone 3: after '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  This zone is mostly empty thanks to '''&amp;lt;code&amp;gt;doAfterIocInit&amp;lt;/code&amp;gt;''' from the '''&amp;lt;code&amp;gt;std&amp;lt;/code&amp;gt;''' module (sequence programs and autosave get initialized here, but the calls that do the initializing appear much earlier in the startup)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: PVs are available during '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;''', even though the IOC is still starting up.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Autosave ===&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;autosave&amp;lt;/code&amp;gt;''' is a synApps module that provides seamless reboot functionality. It is mostly automatic when '''mkioc''' is used. &lt;br /&gt;
PVs are saved while the IOC is running and loaded during '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  &lt;br /&gt;
Autosaved values overwrite database defaults.&lt;br /&gt;
&lt;br /&gt;
Databases with associated req files ('''&amp;lt;code&amp;gt;_settings.req&amp;lt;/code&amp;gt;''') are automatically added to '''&amp;lt;code&amp;gt;built_*.req&amp;lt;/code&amp;gt;''' by autosaveBuild&lt;br /&gt;
Multiple '''&amp;lt;code&amp;gt;.sav&amp;lt;/code&amp;gt;''' files can be created:&lt;br /&gt;
* Default:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav&amp;lt;/code&amp;gt;''' &amp;amp; '''&amp;lt;code&amp;gt;.savB&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** actually restored&lt;br /&gt;
* Periodic:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav0&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;.sav1&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;.sav2&amp;lt;/code&amp;gt;''', …&lt;br /&gt;
** overwritten cyclically&lt;br /&gt;
* Dated:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav-230109-134502&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** written once at boot time&lt;br /&gt;
&lt;br /&gt;
The 1st half of '''&amp;lt;code&amp;gt;common.iocsh&amp;lt;/code&amp;gt;''' sets up autosave:&lt;br /&gt;
[https://github.com/epics-modules/xxx/blob/master/iocBoot/iocxxx/common.iocsh#L1-L46 https://github.com/epics-modules/xxx/blob/master/iocBoot/iocxxx/common.iocsh#L1-L46]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How to build &amp;amp; clean a Linux IOC ===&lt;br /&gt;
&lt;br /&gt;
* Confirm the RHEL version&lt;br /&gt;
** &amp;lt;code&amp;gt; '''uname -r''' → 3.10.0-1160.62.1.'''el7'''.x86_64&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; '''cat /etc/redhat-release''' → Red Hat Enterprise Linux Server release '''7.9'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Set &amp;lt;code&amp;gt; EPICS_HOST_ARCH&amp;lt;/code&amp;gt;  environment variable&lt;br /&gt;
** bash: &amp;lt;code&amp;gt;'''export EPICS_HOST_ARCH=rhel7-x86_64'''&amp;lt;/code&amp;gt;&lt;br /&gt;
** tcsh: &amp;lt;code&amp;gt;'''setenv EPICS_HOST_ARCH rhel7-x86_64'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Initiate the build in the top-level IOC directory&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Remove intermediate build dirs (for the current &amp;lt;code&amp;gt; EPICS_HOST_ARCH&amp;lt;/code&amp;gt; )&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make clean'''&amp;lt;/code&amp;gt; &lt;br /&gt;
* Remove all intermediate build dirs and top-level build directories&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make distclean'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Show all make options&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make help'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running an IOC ==&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use the script ===&lt;br /&gt;
&lt;br /&gt;
==== Create an alias ====&lt;br /&gt;
&lt;br /&gt;
Create an alias for the script (assuming PWD = IOC’s top-level dir)&lt;br /&gt;
:&amp;lt;code&amp;gt;$ '''alias kmp=${PWD}/iocBoot/iockmp/softioc/kmp.sh'''&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;$ '''kmp''' &amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Usage: kmp.sh {console|restart|run|start|caqtdm|medm|status|stop|usage}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Noteworthy arguments:&lt;br /&gt;
* '''&amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt;''': Runs the IOC in the current terminal (doesn't return the command prompt). Useful for troubleshooting.  Problematic for normal operation.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt;''': Runs the IOC in the background (returns the command prompt) using screen or procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;''': Tells you if the IOC is running and refuses to start if it is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Notes&amp;lt;/u&amp;gt;: &lt;br /&gt;
* Use the full path to the IOC’s start script so the alias can be run from any directory (bash syntax shown).&lt;br /&gt;
* &amp;lt;code&amp;gt;EPICS_HOST_ARCH&amp;lt;/code&amp;gt; needs to still be set otherwise the IOC will not start (unless the &amp;lt;code&amp;gt;EPICS_HOST_ARCH&amp;lt;/code&amp;gt; is hard-coded in the start script)&lt;br /&gt;
* The ampersand is needed for synApps_6_2_1 IOCs, but it won’t be needed in the future because it was added to the '''&amp;lt;code&amp;gt;start_caQtDM_xxx&amp;lt;/code&amp;gt;''' script.&lt;br /&gt;
* Bugs in the deployed copy of '''&amp;lt;code&amp;gt;xxx.sh&amp;lt;/code&amp;gt;''' may prevent it from detecting an IOC is running.&lt;br /&gt;
&lt;br /&gt;
==== Start caQtDM ====&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp caqtdm &amp;amp;&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== Start the IOC ====&lt;br /&gt;
&lt;br /&gt;
Starts the IOC in the background (using screen or procServ):&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp start&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
IOCs are usually run in screen or procServ so that: &lt;br /&gt;
* the window in which they’re started can be closed&lt;br /&gt;
* multiple people can connect to them&lt;br /&gt;
* [procServ] allows other user accounts to restart an IOC&lt;br /&gt;
* [procServ] allows users to connect to Windows IOCs&lt;br /&gt;
&lt;br /&gt;
==== Confirm the IOC is running ====&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp status&amp;lt;/code&amp;gt;'''&lt;br /&gt;
:&amp;lt;code&amp;gt;kmp is running (pid=1281733) in a screen session (pid=1281732)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connecting to an IOC’s shell ===&lt;br /&gt;
&lt;br /&gt;
There are many ways to do it:&lt;br /&gt;
&lt;br /&gt;
* Manually connect to an IOC running in screen from the IOC’s host&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''screen -x kmp'''&amp;lt;/code&amp;gt;&lt;br /&gt;
::The -x option will connect even if someone is already connected to the screen session.  &lt;br /&gt;
::The -r option only succeeds if no one is connected to the session.&lt;br /&gt;
&lt;br /&gt;
* Connect to an IOC running in screen or procServ from the IOC’s host&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''kmp console'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Connect to an IOC running in screen or procServ with logging '''from any host'''&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''/APSshare/bin/iocConsole.py iockmp'''&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: iocConsole.py requires ssh access which beamline accounts don't have by default&lt;br /&gt;
&lt;br /&gt;
* Manually connect to an IOC running in procServ from the IOC’s subnet&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''telnet s100bcda 53127'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disconnecting from an IOC’s shell ===&lt;br /&gt;
&lt;br /&gt;
* '''Close the terminal''' that is connected to the screen or procServ session&lt;br /&gt;
** Disconnects from both screen &amp;amp; procServ&lt;br /&gt;
** Kills an IOC running outside of screen &amp;amp; procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Ctrl+a&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;Ctrl+d&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** Disconnects from both screen &amp;amp; procServ&lt;br /&gt;
** Kills an IOC running outside of screen &amp;amp; procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Ctrl+a, d&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** Only disconnects from screen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== IOC shell commands ===&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;help [command]&amp;lt;/code&amp;gt;''' - shows available commands or syntax of specified command&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbpr record_name [0-9]&amp;lt;/code&amp;gt;''' - displays fields and values for a given record&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl&amp;lt;/code&amp;gt;''' - lists all records in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl record_type&amp;lt;/code&amp;gt;''' - lists all records of a specific type in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl record_type &amp;quot;field_list&amp;quot;&amp;lt;/code&amp;gt;''' - lists specified fields (space-separated list) of records of a specific type in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbpf pv_name value&amp;lt;/code&amp;gt;''' - change a PV’s value – analogous to caput&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbgf pv_name&amp;lt;/code&amp;gt;''' - read a PV’s value – analogous to caget&lt;br /&gt;
:'''&amp;lt;code&amp;gt;epicsEnvShow&amp;lt;/code&amp;gt;''' - prints environment variables&lt;br /&gt;
:'''&amp;lt;code&amp;gt;seqShow&amp;lt;/code&amp;gt;''' - shows running sequence programs&lt;br /&gt;
:'''&amp;lt;code&amp;gt;seqStop&amp;lt;/code&amp;gt;''' - stops a running sequence program&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Help:Formatting Help formatting]&lt;br /&gt;
* [https://epics.anl.gov/base/R3-16/2-docs/AppDevGuide/DatabaseDefinition.html#x7-2630006.6 https://epics.anl.gov/]&lt;br /&gt;
* [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_for_Dummies&amp;diff=272</id>
		<title>EPICS for Dummies</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_for_Dummies&amp;diff=272"/>
		<updated>2023-03-08T02:25:31Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* How does support get into an IOC? */ add linking diagram&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is EPICS? ==&lt;br /&gt;
&lt;br /&gt;
EPICS (Experimental Physics and Industrial Control System) is a distributed control system, which means that the IOC (software) can run on a different computer as the user interfaces.&lt;br /&gt;
&lt;br /&gt;
The next 5 sections are dedicated to the definition of basic EPICS components (IOC, PV, record, database, &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;add devices?&amp;lt;/span&amp;gt;). To create your own EPICS support, you can skip directly to [[#How does one create an IOC?]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is an IOC? ==&lt;br /&gt;
&lt;br /&gt;
[[File:EPICS_basics_PV_diagram.png|right|thumb]]&lt;br /&gt;
&lt;br /&gt;
IOC (Input/Output Controller) is a piece of software running on a computer:&lt;br /&gt;
* loads '''databases'''&lt;br /&gt;
* serves something called '''process variables''' (PVs) that you can read and write to&lt;br /&gt;
* used to run on VMEs, but nowadays it runs on anything. &lt;br /&gt;
* usually talks to hardware, but that isn’t a requirement.&lt;br /&gt;
&lt;br /&gt;
IOCs are started with startup scripts. Those scripts tell the IOC what database files to load and where those files are. When the IOC is told to load a database, what it is doing is parsing that database file, identifying the records that are contained within, and then generating the actual epics PVs that a user will interact with.&lt;br /&gt;
&lt;br /&gt;
'''Records''' and '''databases''' (lists of records) are configuration files describing the initial setup for '''PVs''', the '''IOC''' is the software that manages the behavior of PVs and communication to get/set their values.&lt;br /&gt;
&lt;br /&gt;
== What is a PV? ==&lt;br /&gt;
&lt;br /&gt;
PV (Process Variable) is a the field from a record: &lt;br /&gt;
 ''PV = record_name + . + field_name''&lt;br /&gt;
&lt;br /&gt;
Most of the interactive parts of user displays have PVs associated with them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a record? ==&lt;br /&gt;
&lt;br /&gt;
Records are the building blocks of EPICS:&lt;br /&gt;
* There is a lot of different types of record, and each type is designed to perform a specific function &lt;br /&gt;
* Records are customizable via fields that allow users to configure how they behave and monitor their state (see [[#More about record fields]] to know how to learn about record fields)&lt;br /&gt;
* Records do nothing until they are processed (see [[#SCAN, PROC &amp;amp; FLNK fields]])&lt;br /&gt;
* Records vary significantly in complexity (see [[#More about records]])&lt;br /&gt;
* It is rare for new records to be created, now that ''asyn'' device support exists &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;add link to asyn?&amp;lt;/span&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Where do records come from? ===&lt;br /&gt;
&lt;br /&gt;
Typically, records at the APS comes from either:&lt;br /&gt;
* '''[https://epics.anl.gov/base/index.php EPICS base]''': main core of EPICS&lt;br /&gt;
* '''[https://www.aps.anl.gov/BCDA/synApps synApps]''': a collection of EPICS modules that are commonly used at the APS&lt;br /&gt;
A module is similar to a python package: it is an already written set of databases and associated behavior you can load into your IOC to do certain things, for example talk to specific hardware. An IOC can link to several modules.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ Records in synApps modules &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Module !! Records !! Module !! Records&lt;br /&gt;
|-&lt;br /&gt;
| alive || alive || motor || motor&lt;br /&gt;
|-&lt;br /&gt;
| asyn || asyn || optics || table&lt;br /&gt;
|-&lt;br /&gt;
| busy || busy || scaler || scaler&lt;br /&gt;
|-&lt;br /&gt;
| calc || acalcout, scalcout, sseq, swait, transform || sscan || sscan&lt;br /&gt;
|-&lt;br /&gt;
| camac || camac || std || epid, timestamp, throttle&lt;br /&gt;
|-&lt;br /&gt;
| lua || luascript || vac || digitel, vs&lt;br /&gt;
|-&lt;br /&gt;
| mca || mca || vme || vme&lt;br /&gt;
|-&lt;br /&gt;
| allenBradley || ab1771IFE, ab1771N, ab1771IX, ...|| allenBradley || ..., ab1791, abDcm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If a record isn't listed here, it probably comes from EPICS base. &lt;br /&gt;
The advantage to using synApps over a collection of modules one assembles on their own is that some amount of BCDA testing has been done.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What is a record field? ===&lt;br /&gt;
&lt;br /&gt;
Record fields are controllable or informative properties of a record.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Noteworthy fields====&lt;br /&gt;
&lt;br /&gt;
*'''VAL''' - the default field (used if no field is specified in the vast majority of cases)&lt;br /&gt;
*'''SCAN''' - determines when a record processes&lt;br /&gt;
*'''NAME''' - the record name (helpful if records are aliased)&lt;br /&gt;
*'''DESC''' - record description&lt;br /&gt;
*'''RTYP''' - the record type&lt;br /&gt;
*'''DTYP''' - the device support type (not meaningful for all record types)&lt;br /&gt;
*'''DISP''' - disable puts (ca = channel access &amp;amp; pva = pv access) from outside the IOC (when non-zero); e.g. disable a motor from the motorx_all screen&lt;br /&gt;
*'''DISV/DISA/SDIS''' - disable record processing internally &lt;br /&gt;
**Record processing is disabled when '''DISA''' equals '''DISV''' (e.g. uses SDIS field to read in a value/mode, which will disable some control if a certain mode is active)&lt;br /&gt;
**'''DISA''' is set to the value of the PV in the '''SDIS''' field, if it isn't empty&lt;br /&gt;
*'''TPRO''' - trace processing: when set to 1 prints out all the records that get processed after the record is processed; used only for troubleshooting&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: some of the fields of a record are actually record attributes (they return the same value for all instances of the record type; see [https://epics.anl.gov/base/R3-16/2-docs/AppDevGuide/DatabaseDefinition.html#x7-2630006.6 https://epics.anl.gov/])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== SCAN, PROC &amp;amp; FLNK fields ====&lt;br /&gt;
&lt;br /&gt;
Records do nothing until they are processed. Records can be processed multiple ways:&lt;br /&gt;
* &amp;lt;u&amp;gt;Manually&amp;lt;/u&amp;gt;:&lt;br /&gt;
** Write 1 (or any non-zero value) to a record’s '''PROC''' field&lt;br /&gt;
**Forward link ('''FLNK''') from another record&lt;br /&gt;
* &amp;lt;u&amp;gt;Periodically&amp;lt;/u&amp;gt; by setting the '''SCAN''' field to something other than &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ SCAN field options &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Index !! Option !! Index !! Option&lt;br /&gt;
|-&lt;br /&gt;
| 0 || &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;   || 5 || &amp;lt;code&amp;gt;2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt;     || 6 || &amp;lt;code&amp;gt;1 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2 || &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt;  ||7 || &amp;lt;code&amp;gt;0.5 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 3 || &amp;lt;code&amp;gt;10 second&amp;lt;/code&amp;gt;  ||8 || &amp;lt;code&amp;gt;0.2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4 || &amp;lt;code&amp;gt;5 second&amp;lt;/code&amp;gt;  ||9 || &amp;lt;code&amp;gt;0.1 second&amp;lt;/code&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* If a record’s SCAN field is not specified in a database, it defaults to &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.  &lt;br /&gt;
* The '''SCAN''' field is common to ''all'' record types and the options can be selected by index instead of by string.&lt;br /&gt;
* &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt; processes a record when the driver gets a new value, but is device/driver dependent and isn’t guaranteed to work&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Record link types ===&lt;br /&gt;
&lt;br /&gt;
Much of the power of EPICS comes from the ability to link EPICS records together.&lt;br /&gt;
There are two link implementations: standard and dynamic.  &lt;br /&gt;
* Dynamic links (pink) are found on ''userCalc'' ('''swait''' records) and ''scan'' ('''sscan''' records) screens; this type of link accept only a PV name. THe role of the process command (see below) is taken in a separate field.   &lt;br /&gt;
* Standard links (purple) are found everywhere else.&lt;br /&gt;
''inlinkHelp'' and ''outlinkHelp'' are accessible from userTransform screens and scaler screens (for the later only).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Input Links ====&lt;br /&gt;
&lt;br /&gt;
Input links read a value from another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an input link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just read the value; don't process the target record (i.e. read a potentially stale value); this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Process the target record and then read a value from it.&lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Read a value without causing processing to occur.&lt;br /&gt;
* &amp;lt;code&amp;gt;CP&amp;lt;/code&amp;gt; - Process linking record every time the target record processes.&lt;br /&gt;
* &amp;lt;code&amp;gt;CPP&amp;lt;/code&amp;gt; - Same as CP, but linking record process only if its SCAN field has the value &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: ''inlinkHelp'' is accessible from userTransform screens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Output Links ====&lt;br /&gt;
&lt;br /&gt;
Output links write a value to another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an output link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just write a value; don't process the target record; this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Write a value and then process the target record. To be use if you want EPICS to trace processing (&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;= wait for completion?&amp;lt;/span&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Write a value; let the target record decide whether or not to process (as it would if you typed the value by hand); if the processing does occur, EPICS will not trace it. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: &lt;br /&gt;
* The default link process command, &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;, is '''almost never the desired behavior''' for output links. Change &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; immediately and revert if problems are discovered.&lt;br /&gt;
* If the target PV is itself a link field, you must specify the command &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt;; if you want to wait for completion in this case, you must use either the '''sseq''' or the '''sCalcout''' record, select &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; and set the link's '''WAIT''' field to &amp;lt;code&amp;gt;Wait&amp;lt;/code&amp;gt;&lt;br /&gt;
* ''outlinkHelp'' is accessible from userTransform and scaler screens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Forward Links ====&lt;br /&gt;
&lt;br /&gt;
Forward link look like output links; they are purple on user displays, but they don't auto-populate with process &amp;amp; alarm commands. &lt;br /&gt;
Forward link causes the linked record to process when the record containing the forward link is processed&lt;br /&gt;
* Linked record is in the same IOC ('''PROC''' field for linked record is optional):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
* Linked record is in a different IOC ('''PROC''' field for linked record is required):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* Forwarding-linking records in the same IOC by only specifying the record name is an exception to the &amp;quot;'''VAL''' ''is the default field''&amp;quot; rule.&lt;br /&gt;
* When omitting the '''PROC''' field of a linked record in a different IOC, nothing will happen but you won't get any error message.&lt;br /&gt;
* Always specify the '''PROC''' field to avoid problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More about records ===&lt;br /&gt;
&lt;br /&gt;
* Records vary significantly in complexity; one way to classify them would be (*):&lt;br /&gt;
** Simple records are associated with individual data types&lt;br /&gt;
*::;bi, bo, mbbi, mbbo, longin, longout, ai, ao, stringin, stringout, waveform&lt;br /&gt;
** Intermediate records often perform calculations or link multiple records&lt;br /&gt;
*::;calcout, scalcout, acalcout, swait, transform, fanout, dfanout&lt;br /&gt;
** Complex records are associated with devices or higher-level functionality&lt;br /&gt;
*::;motor, scaler, mca, sscan, table, digitel, vs&lt;br /&gt;
** Flexible records allow custom functionality to be implemented&lt;br /&gt;
*::;sub, aSub, luascript&lt;br /&gt;
(*) this is not an official classification, nor an exhaustive list of records.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* areaDetector databases are composed of mostly simple record.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More about record fields ===&lt;br /&gt;
&lt;br /&gt;
To find documentation for a specific field you need to know/find answers to the following questions:&lt;br /&gt;
* Is the field common to all or input/output record types?  &lt;br /&gt;
* If not, does the record come from EPICS base or a different EPICS module (synApps)?&lt;br /&gt;
** The [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation] is the best place to find information about record types that come from EPICS base. &amp;lt;br&amp;gt;Field documentation appears in multiple locations:&lt;br /&gt;
*** Fields common to all record types&lt;br /&gt;
*** Fields common to input record types&lt;br /&gt;
*** Fields common to output record types&lt;br /&gt;
*** Record-specific documentation&lt;br /&gt;
** synApps record reference documentation&lt;br /&gt;
*** In each module's documentation directory&lt;br /&gt;
**** [https://github.com/epics-modules https://github.com/epics-modules]&lt;br /&gt;
**** &amp;lt;code&amp;gt;/APSshare/epics/synApps_X_Y/support&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a databases? ==&lt;br /&gt;
&lt;br /&gt;
A database is just a text file with a '''.db''' (or '''.template''') extension containing a collection of records that are related. &lt;br /&gt;
&lt;br /&gt;
Databases are generalized with macros to allow multiple instances to be loaded (e.g. $(P)):&lt;br /&gt;
* Macros are variables containing strings to be substituted when the database is loaded.&lt;br /&gt;
* Macros without default values are required to load the database; there is no easy way to figure out what those are for a given database other than looking at the file itself.&lt;br /&gt;
* Macros required by the database should match the macros required by associated screens &amp;amp; autosave (.req) files.&lt;br /&gt;
* The P (prefix) macro usually includes a colon (:), which is the standard separator used in PV names.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How are databases loaded? ===&lt;br /&gt;
&lt;br /&gt;
There are 2 ways to load databases which are strictly equivalent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== dbLoadRecords ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam1,PORT=serial1,A=01&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam2,PORT=serial1,A=02&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== dbLoadTemplate ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadTemplate(&amp;quot;substitutions/ADAM_4018.substitutions&amp;quot;,&amp;quot;P=kmp:&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ADAM_4018.substitutions:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;file &amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;&lt;br /&gt;
 {&lt;br /&gt;
 pattern&lt;br /&gt;
 {R,PORT,A}&lt;br /&gt;
 {adam1, serial1,01}&lt;br /&gt;
 {adam2, serial1,02}&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a device? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;What is a device?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How does one create an IOC? ==&lt;br /&gt;
&lt;br /&gt;
There are multiple ways to create an IOC, but no one does it from scratch:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The EPICS base approach ===&lt;br /&gt;
It creates a bare bones IOC but requires more knowledge of the EPICS build system to get started:&lt;br /&gt;
::'''&amp;lt;code&amp;gt;makeBaseApp.pl&amp;lt;/code&amp;gt;'''&lt;br /&gt;
* Must be run multiple times&lt;br /&gt;
* Creates IOC contents in the current directory&lt;br /&gt;
* synApps support needs to be added manually&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The synApps approach ===&lt;br /&gt;
&lt;br /&gt;
It is based on the ''xxx'' module and designed to give you a usable IOC with as little effort as possible:&lt;br /&gt;
::'''&amp;lt;code&amp;gt;mkioc&amp;lt;/code&amp;gt;'''&lt;br /&gt;
 &lt;br /&gt;
* A single command leaves you with an IOC you can build:&lt;br /&gt;
::&amp;lt;code&amp;gt;/APSshare/bin/mkioc -n -f -s 6-2-1 kmp&amp;lt;/code&amp;gt;&lt;br /&gt;
* Creates a top-level IOC directory in the current directory&lt;br /&gt;
* Common synApps support is included by default&lt;br /&gt;
* mkioc will ask you questions if you run it without options&lt;br /&gt;
&lt;br /&gt;
Note: The BCDA convention is to name development IOCs using the developer's initials (here ''kmp'').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IOC Layout ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The IOC layout can be overwhelming and confusing to those who aren’t yet familiar with it. The EPICS build system creates many directories, making it harder to find the important directories.&lt;br /&gt;
Important files are often buried multiple directories down from the top-level. It is helpful to look at subsets of the IOC directory.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;17&amp;quot;; style=&amp;quot;color:blue&amp;quot;|kmp&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|bin&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:red&amp;quot;|rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|configure&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:red&amp;quot;|db&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:red&amp;quot;|dbd&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;4&amp;quot;|iocBoot&lt;br /&gt;
|rowspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:green&amp;quot;|iockmp&lt;br /&gt;
|autosave&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:green&amp;quot;|iocsh&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:blue&amp;quot;| softioc&lt;br /&gt;
| commands&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:green&amp;quot;| substitutions&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;6&amp;quot;|kmpApp&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|Db&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|op&lt;br /&gt;
|adl&lt;br /&gt;
|-&lt;br /&gt;
|ui&lt;br /&gt;
| autoconvert&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|src&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|lib&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:red&amp;quot;|rhel8-x86_64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Build configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: orange&amp;quot;&amp;gt;Orange&amp;lt;/span&amp;gt; folders:&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/configure&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the files that specify which versions of EPICS base and EPICS modules should be should be used when building the IOC.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/kmpApp/Db&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains local databases (and associated autosave files) and protocol files used by the IOC.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/kmpApp/src&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the Makefile that determines all of the software that gets built into the IOC binary. ; local sequence programs and other EPICS support that needs to be compiled go here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Intermediate build directories ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: grey&amp;quot;&amp;gt;Grey&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
The EPICS Build system will generate '''&amp;lt;code&amp;gt;O.&amp;lt;/code&amp;gt;''' files (Common, EPICS HOST and TARGET architectures) in the configure, Db, and src directory.  These directories are not needed after the IOC is built and can be removed with the '''&amp;lt;code&amp;gt;make clean&amp;lt;/code&amp;gt;''' command. If they are not removed, they can be safely ignored.  It is highly unlikely that you will ever need to look at any of the files in them.&lt;br /&gt;
&lt;br /&gt;
=== Build products ===&lt;br /&gt;
&lt;br /&gt;
The EPICS build system creates top level bin, db, dbd, and lib directories (&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;red&amp;lt;/span&amp;gt; folders):  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/bin/rehl8-x86_64&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the architecture-specific IOC binary (or munch file for VxWorks IOCs).  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/db&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains installed database files which may or may not be used, since many IOCs reference the databases in the Db directory instead.  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/dbd&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains a single database definition file to be loaded by the IOC. &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/lib/rehl8-x86_64&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains architecture-specific files for EPICS modules, but should be empty for the IOC.&amp;lt;br&amp;gt;&lt;br /&gt;
The build system creates an envPaths file in the startup directory, which contains the locations of the modules defined in the RELEASE file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Run-time configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;Green&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The iockmp directory is referred to as the ''startup'' directory.  It contains the '''&amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt;''' file, which is the runtime configuration for the IOC &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;what means runtime?&amp;lt;/span&amp;gt;  &lt;br /&gt;
The IOC’s config is often broken into separate '''&amp;lt;code&amp;gt;.iocsh&amp;lt;/code&amp;gt;''' (or '''&amp;lt;code&amp;gt;.cmd&amp;lt;/code&amp;gt;''') files so that support can be more easily commented out and to improve readability.  &lt;br /&gt;
Substitutions and iocsh files usually reside in subdirectories to reduce clutter in the startup directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Start scripts ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Blue&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
The top-level IOC directory contains scripts that start medm/caQtDM.&lt;br /&gt;
The softioc subdirectory of the startup dir contains a bash script which simplifies managing the IOC on Linux.&lt;br /&gt;
Windows IOCs: the startup directory contains batch files to start the IOC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: The startup directory can reside elsewhere.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How does support get into an IOC? ==&lt;br /&gt;
&lt;br /&gt;
[[File:EPICS_basics_linking_diagrams.png|right|thumb|800px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Quick overview ===&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;configure/RELEASE&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** Defines the locations of EPICS base and EPICS modules&lt;br /&gt;
** Often includes other RELEASE files&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmpApp/src/Makefile&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** Specifies which database definitions (dbd) to include&lt;br /&gt;
** Specifies which libraries should be included in the IOC binary&lt;br /&gt;
** Specifies which local code should be included in the IOC binary&lt;br /&gt;
** Libraries will not be included unless an associated dbd file is included&lt;br /&gt;
** The order of the libraries is important (single-pass linker)&lt;br /&gt;
* '''&amp;lt;code&amp;gt;iocBoot/iockmp/st.cmd&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** The primary IOC config file that is sourced when the IOC is started&lt;br /&gt;
** Name can vary slightly based on how the IOC was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Startup script &amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Legacy IOCs often have monolithic '''&amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt;''' files. Newer IOCs source more '''&amp;lt;code&amp;gt;.iocsh&amp;lt;/code&amp;gt;''' files from EPICS modules, which makes it easier to keep an IOC's config up-to-date.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt; envPaths&lt;br /&gt;
 &lt;br /&gt;
 dbLoadDatabase(&amp;quot;../../dbd/iockmpLinux.dbd&amp;quot;)&lt;br /&gt;
 iockmpLinux_registerRecordDeviceDriver(pdbbase)&lt;br /&gt;
 &lt;br /&gt;
 ### Databases are loaded&lt;br /&gt;
 ### Drivers are initialized/configured here&lt;br /&gt;
 &lt;br /&gt;
 iocInit&lt;br /&gt;
 &lt;br /&gt;
 ### Sequence programs &amp;amp; autosave are started here&lt;br /&gt;
 &lt;br /&gt;
 dbl &amp;gt; dbl-all.txt&lt;br /&gt;
 &lt;br /&gt;
 date&lt;br /&gt;
&lt;br /&gt;
We can break it up into 3 functional zones:&lt;br /&gt;
* Zone 1: before '''&amp;lt;code&amp;gt;dbLoadDatabase&amp;lt;/code&amp;gt;'''.  Usually this is where env vars and paths are defined.&lt;br /&gt;
* Zone 2: after '''&amp;lt;code&amp;gt;dbLoadDatabase&amp;lt;/code&amp;gt;''' &amp;amp; before '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  Databases can only be loaded here.&lt;br /&gt;
* Zone 3: after '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  This zone is mostly empty thanks to '''&amp;lt;code&amp;gt;doAfterIocInit&amp;lt;/code&amp;gt;''' from the '''&amp;lt;code&amp;gt;std&amp;lt;/code&amp;gt;''' module (sequence programs and autosave get initialized here, but the calls that do the initializing appear much earlier in the startup)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: PVs are available during '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;''', even though the IOC is still starting up.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Autosave ===&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;autosave&amp;lt;/code&amp;gt;''' is a synApps module that provides seamless reboot functionality. It is mostly automatic when '''mkioc''' is used. &lt;br /&gt;
PVs are saved while the IOC is running and loaded during '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  &lt;br /&gt;
Autosaved values overwrite database defaults.&lt;br /&gt;
&lt;br /&gt;
Databases with associated req files ('''&amp;lt;code&amp;gt;_settings.req&amp;lt;/code&amp;gt;''') are automatically added to '''&amp;lt;code&amp;gt;built_*.req&amp;lt;/code&amp;gt;''' by autosaveBuild&lt;br /&gt;
Multiple '''&amp;lt;code&amp;gt;.sav&amp;lt;/code&amp;gt;''' files can be created:&lt;br /&gt;
* Default:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav&amp;lt;/code&amp;gt;''' &amp;amp; '''&amp;lt;code&amp;gt;.savB&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** actually restored&lt;br /&gt;
* Periodic:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav0&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;.sav1&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;.sav2&amp;lt;/code&amp;gt;''', …&lt;br /&gt;
** overwritten cyclically&lt;br /&gt;
* Dated:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav-230109-134502&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** written once at boot time&lt;br /&gt;
&lt;br /&gt;
The 1st half of '''&amp;lt;code&amp;gt;common.iocsh&amp;lt;/code&amp;gt;''' sets up autosave:&lt;br /&gt;
[https://github.com/epics-modules/xxx/blob/master/iocBoot/iocxxx/common.iocsh#L1-L46 https://github.com/epics-modules/xxx/blob/master/iocBoot/iocxxx/common.iocsh#L1-L46]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How to build &amp;amp; clean a Linux IOC ===&lt;br /&gt;
&lt;br /&gt;
* Confirm the RHEL version&lt;br /&gt;
** &amp;lt;code&amp;gt; '''uname -r''' → 3.10.0-1160.62.1.'''el7'''.x86_64&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; '''cat /etc/redhat-release''' → Red Hat Enterprise Linux Server release '''7.9'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Set &amp;lt;code&amp;gt; EPICS_HOST_ARCH&amp;lt;/code&amp;gt;  environment variable&lt;br /&gt;
** bash: &amp;lt;code&amp;gt;'''export EPICS_HOST_ARCH=rhel7-x86_64'''&amp;lt;/code&amp;gt;&lt;br /&gt;
** tcsh: &amp;lt;code&amp;gt;'''setenv EPICS_HOST_ARCH rhel7-x86_64'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Initiate the build in the top-level IOC directory&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Remove intermediate build dirs (for the current &amp;lt;code&amp;gt; EPICS_HOST_ARCH&amp;lt;/code&amp;gt; )&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make clean'''&amp;lt;/code&amp;gt; &lt;br /&gt;
* Remove all intermediate build dirs and top-level build directories&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make distclean'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Show all make options&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make help'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running an IOC ==&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use the script ===&lt;br /&gt;
&lt;br /&gt;
==== Create an alias ====&lt;br /&gt;
&lt;br /&gt;
Create an alias for the script (assuming PWD = IOC’s top-level dir)&lt;br /&gt;
:&amp;lt;code&amp;gt;$ '''alias kmp=${PWD}/iocBoot/iockmp/softioc/kmp.sh'''&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;$ '''kmp''' &amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Usage: kmp.sh {console|restart|run|start|caqtdm|medm|status|stop|usage}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Noteworthy arguments:&lt;br /&gt;
* '''&amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt;''': Runs the IOC in the current terminal (doesn't return the command prompt). Useful for troubleshooting.  Problematic for normal operation.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt;''': Runs the IOC in the background (returns the command prompt) using screen or procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;''': Tells you if the IOC is running and refuses to start if it is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Notes&amp;lt;/u&amp;gt;: &lt;br /&gt;
* Use the full path to the IOC’s start script so the alias can be run from any directory (bash syntax shown).&lt;br /&gt;
* &amp;lt;code&amp;gt;EPICS_HOST_ARCH&amp;lt;/code&amp;gt; needs to still be set otherwise the IOC will not start (unless the &amp;lt;code&amp;gt;EPICS_HOST_ARCH&amp;lt;/code&amp;gt; is hard-coded in the start script)&lt;br /&gt;
* The ampersand is needed for synApps_6_2_1 IOCs, but it won’t be needed in the future because it was added to the '''&amp;lt;code&amp;gt;start_caQtDM_xxx&amp;lt;/code&amp;gt;''' script.&lt;br /&gt;
* Bugs in the deployed copy of '''&amp;lt;code&amp;gt;xxx.sh&amp;lt;/code&amp;gt;''' may prevent it from detecting an IOC is running.&lt;br /&gt;
&lt;br /&gt;
==== Start caQtDM ====&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp caqtdm &amp;amp;&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== Start the IOC ====&lt;br /&gt;
&lt;br /&gt;
Starts the IOC in the background (using screen or procServ):&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp start&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
IOCs are usually run in screen or procServ so that: &lt;br /&gt;
* the window in which they’re started can be closed&lt;br /&gt;
* multiple people can connect to them&lt;br /&gt;
* [procServ] allows other user accounts to restart an IOC&lt;br /&gt;
* [procServ] allows users to connect to Windows IOCs&lt;br /&gt;
&lt;br /&gt;
==== Confirm the IOC is running ====&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp status&amp;lt;/code&amp;gt;'''&lt;br /&gt;
:&amp;lt;code&amp;gt;kmp is running (pid=1281733) in a screen session (pid=1281732)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connecting to an IOC’s shell ===&lt;br /&gt;
&lt;br /&gt;
There are many ways to do it:&lt;br /&gt;
&lt;br /&gt;
* Manually connect to an IOC running in screen from the IOC’s host&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''screen -x kmp'''&amp;lt;/code&amp;gt;&lt;br /&gt;
::The -x option will connect even if someone is already connected to the screen session.  &lt;br /&gt;
::The -r option only succeeds if no one is connected to the session.&lt;br /&gt;
&lt;br /&gt;
* Connect to an IOC running in screen or procServ from the IOC’s host&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''kmp console'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Connect to an IOC running in screen or procServ with logging '''from any host'''&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''/APSshare/bin/iocConsole.py iockmp'''&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: iocConsole.py requires ssh access which beamline accounts don't have by default&lt;br /&gt;
&lt;br /&gt;
* Manually connect to an IOC running in procServ from the IOC’s subnet&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''telnet s100bcda 53127'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disconnecting from an IOC’s shell ===&lt;br /&gt;
&lt;br /&gt;
* '''Close the terminal''' that is connected to the screen or procServ session&lt;br /&gt;
** Disconnects from both screen &amp;amp; procServ&lt;br /&gt;
** Kills an IOC running outside of screen &amp;amp; procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Ctrl+a&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;Ctrl+d&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** Disconnects from both screen &amp;amp; procServ&lt;br /&gt;
** Kills an IOC running outside of screen &amp;amp; procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Ctrl+a, d&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** Only disconnects from screen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== IOC shell commands ===&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;help [command]&amp;lt;/code&amp;gt;''' - shows available commands or syntax of specified command&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbpr record_name [0-9]&amp;lt;/code&amp;gt;''' - displays fields and values for a given record&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl&amp;lt;/code&amp;gt;''' - lists all records in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl record_type&amp;lt;/code&amp;gt;''' - lists all records of a specific type in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl record_type &amp;quot;field_list&amp;quot;&amp;lt;/code&amp;gt;''' - lists specified fields (space-separated list) of records of a specific type in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbpf pv_name value&amp;lt;/code&amp;gt;''' - change a PV’s value – analogous to caput&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbgf pv_name&amp;lt;/code&amp;gt;''' - read a PV’s value – analogous to caget&lt;br /&gt;
:'''&amp;lt;code&amp;gt;epicsEnvShow&amp;lt;/code&amp;gt;''' - prints environment variables&lt;br /&gt;
:'''&amp;lt;code&amp;gt;seqShow&amp;lt;/code&amp;gt;''' - shows running sequence programs&lt;br /&gt;
:'''&amp;lt;code&amp;gt;seqStop&amp;lt;/code&amp;gt;''' - stops a running sequence program&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Help:Formatting Help formatting]&lt;br /&gt;
* [https://epics.anl.gov/base/R3-16/2-docs/AppDevGuide/DatabaseDefinition.html#x7-2630006.6 https://epics.anl.gov/]&lt;br /&gt;
* [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_for_Dummies&amp;diff=271</id>
		<title>EPICS for Dummies</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=EPICS_for_Dummies&amp;diff=271"/>
		<updated>2023-03-08T02:23:45Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* What is an IOC? */ add diagram&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is EPICS? ==&lt;br /&gt;
&lt;br /&gt;
EPICS (Experimental Physics and Industrial Control System) is a distributed control system, which means that the IOC (software) can run on a different computer as the user interfaces.&lt;br /&gt;
&lt;br /&gt;
The next 5 sections are dedicated to the definition of basic EPICS components (IOC, PV, record, database, &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;add devices?&amp;lt;/span&amp;gt;). To create your own EPICS support, you can skip directly to [[#How does one create an IOC?]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is an IOC? ==&lt;br /&gt;
&lt;br /&gt;
[[File:EPICS_basics_PV_diagram.png|right|thumb]]&lt;br /&gt;
&lt;br /&gt;
IOC (Input/Output Controller) is a piece of software running on a computer:&lt;br /&gt;
* loads '''databases'''&lt;br /&gt;
* serves something called '''process variables''' (PVs) that you can read and write to&lt;br /&gt;
* used to run on VMEs, but nowadays it runs on anything. &lt;br /&gt;
* usually talks to hardware, but that isn’t a requirement.&lt;br /&gt;
&lt;br /&gt;
IOCs are started with startup scripts. Those scripts tell the IOC what database files to load and where those files are. When the IOC is told to load a database, what it is doing is parsing that database file, identifying the records that are contained within, and then generating the actual epics PVs that a user will interact with.&lt;br /&gt;
&lt;br /&gt;
'''Records''' and '''databases''' (lists of records) are configuration files describing the initial setup for '''PVs''', the '''IOC''' is the software that manages the behavior of PVs and communication to get/set their values.&lt;br /&gt;
&lt;br /&gt;
== What is a PV? ==&lt;br /&gt;
&lt;br /&gt;
PV (Process Variable) is a the field from a record: &lt;br /&gt;
 ''PV = record_name + . + field_name''&lt;br /&gt;
&lt;br /&gt;
Most of the interactive parts of user displays have PVs associated with them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a record? ==&lt;br /&gt;
&lt;br /&gt;
Records are the building blocks of EPICS:&lt;br /&gt;
* There is a lot of different types of record, and each type is designed to perform a specific function &lt;br /&gt;
* Records are customizable via fields that allow users to configure how they behave and monitor their state (see [[#More about record fields]] to know how to learn about record fields)&lt;br /&gt;
* Records do nothing until they are processed (see [[#SCAN, PROC &amp;amp; FLNK fields]])&lt;br /&gt;
* Records vary significantly in complexity (see [[#More about records]])&lt;br /&gt;
* It is rare for new records to be created, now that ''asyn'' device support exists &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;add link to asyn?&amp;lt;/span&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Where do records come from? ===&lt;br /&gt;
&lt;br /&gt;
Typically, records at the APS comes from either:&lt;br /&gt;
* '''[https://epics.anl.gov/base/index.php EPICS base]''': main core of EPICS&lt;br /&gt;
* '''[https://www.aps.anl.gov/BCDA/synApps synApps]''': a collection of EPICS modules that are commonly used at the APS&lt;br /&gt;
A module is similar to a python package: it is an already written set of databases and associated behavior you can load into your IOC to do certain things, for example talk to specific hardware. An IOC can link to several modules.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ Records in synApps modules &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Module !! Records !! Module !! Records&lt;br /&gt;
|-&lt;br /&gt;
| alive || alive || motor || motor&lt;br /&gt;
|-&lt;br /&gt;
| asyn || asyn || optics || table&lt;br /&gt;
|-&lt;br /&gt;
| busy || busy || scaler || scaler&lt;br /&gt;
|-&lt;br /&gt;
| calc || acalcout, scalcout, sseq, swait, transform || sscan || sscan&lt;br /&gt;
|-&lt;br /&gt;
| camac || camac || std || epid, timestamp, throttle&lt;br /&gt;
|-&lt;br /&gt;
| lua || luascript || vac || digitel, vs&lt;br /&gt;
|-&lt;br /&gt;
| mca || mca || vme || vme&lt;br /&gt;
|-&lt;br /&gt;
| allenBradley || ab1771IFE, ab1771N, ab1771IX, ...|| allenBradley || ..., ab1791, abDcm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If a record isn't listed here, it probably comes from EPICS base. &lt;br /&gt;
The advantage to using synApps over a collection of modules one assembles on their own is that some amount of BCDA testing has been done.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== What is a record field? ===&lt;br /&gt;
&lt;br /&gt;
Record fields are controllable or informative properties of a record.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Noteworthy fields====&lt;br /&gt;
&lt;br /&gt;
*'''VAL''' - the default field (used if no field is specified in the vast majority of cases)&lt;br /&gt;
*'''SCAN''' - determines when a record processes&lt;br /&gt;
*'''NAME''' - the record name (helpful if records are aliased)&lt;br /&gt;
*'''DESC''' - record description&lt;br /&gt;
*'''RTYP''' - the record type&lt;br /&gt;
*'''DTYP''' - the device support type (not meaningful for all record types)&lt;br /&gt;
*'''DISP''' - disable puts (ca = channel access &amp;amp; pva = pv access) from outside the IOC (when non-zero); e.g. disable a motor from the motorx_all screen&lt;br /&gt;
*'''DISV/DISA/SDIS''' - disable record processing internally &lt;br /&gt;
**Record processing is disabled when '''DISA''' equals '''DISV''' (e.g. uses SDIS field to read in a value/mode, which will disable some control if a certain mode is active)&lt;br /&gt;
**'''DISA''' is set to the value of the PV in the '''SDIS''' field, if it isn't empty&lt;br /&gt;
*'''TPRO''' - trace processing: when set to 1 prints out all the records that get processed after the record is processed; used only for troubleshooting&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: some of the fields of a record are actually record attributes (they return the same value for all instances of the record type; see [https://epics.anl.gov/base/R3-16/2-docs/AppDevGuide/DatabaseDefinition.html#x7-2630006.6 https://epics.anl.gov/])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== SCAN, PROC &amp;amp; FLNK fields ====&lt;br /&gt;
&lt;br /&gt;
Records do nothing until they are processed. Records can be processed multiple ways:&lt;br /&gt;
* &amp;lt;u&amp;gt;Manually&amp;lt;/u&amp;gt;:&lt;br /&gt;
** Write 1 (or any non-zero value) to a record’s '''PROC''' field&lt;br /&gt;
**Forward link ('''FLNK''') from another record&lt;br /&gt;
* &amp;lt;u&amp;gt;Periodically&amp;lt;/u&amp;gt; by setting the '''SCAN''' field to something other than &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;margin-left: 100px; margin-right:auto&amp;quot;&lt;br /&gt;
|+ SCAN field options &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Index !! Option !! Index !! Option&lt;br /&gt;
|-&lt;br /&gt;
| 0 || &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;   || 5 || &amp;lt;code&amp;gt;2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt;     || 6 || &amp;lt;code&amp;gt;1 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2 || &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt;  ||7 || &amp;lt;code&amp;gt;0.5 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 3 || &amp;lt;code&amp;gt;10 second&amp;lt;/code&amp;gt;  ||8 || &amp;lt;code&amp;gt;0.2 second&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4 || &amp;lt;code&amp;gt;5 second&amp;lt;/code&amp;gt;  ||9 || &amp;lt;code&amp;gt;0.1 second&amp;lt;/code&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* If a record’s SCAN field is not specified in a database, it defaults to &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.  &lt;br /&gt;
* The '''SCAN''' field is common to ''all'' record types and the options can be selected by index instead of by string.&lt;br /&gt;
* &amp;lt;code&amp;gt;I/O Intr&amp;lt;/code&amp;gt; processes a record when the driver gets a new value, but is device/driver dependent and isn’t guaranteed to work&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Record link types ===&lt;br /&gt;
&lt;br /&gt;
Much of the power of EPICS comes from the ability to link EPICS records together.&lt;br /&gt;
There are two link implementations: standard and dynamic.  &lt;br /&gt;
* Dynamic links (pink) are found on ''userCalc'' ('''swait''' records) and ''scan'' ('''sscan''' records) screens; this type of link accept only a PV name. THe role of the process command (see below) is taken in a separate field.   &lt;br /&gt;
* Standard links (purple) are found everywhere else.&lt;br /&gt;
''inlinkHelp'' and ''outlinkHelp'' are accessible from userTransform screens and scaler screens (for the later only).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Input Links ====&lt;br /&gt;
&lt;br /&gt;
Input links read a value from another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an input link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just read the value; don't process the target record (i.e. read a potentially stale value); this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Process the target record and then read a value from it.&lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Read a value without causing processing to occur.&lt;br /&gt;
* &amp;lt;code&amp;gt;CP&amp;lt;/code&amp;gt; - Process linking record every time the target record processes.&lt;br /&gt;
* &amp;lt;code&amp;gt;CPP&amp;lt;/code&amp;gt; - Same as CP, but linking record process only if its SCAN field has the value &amp;lt;code&amp;gt;Passive&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: ''inlinkHelp'' is accessible from userTransform screens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Output Links ====&lt;br /&gt;
&lt;br /&gt;
Output links write a value to another PV. It accepts a PV name followed by a process command (e.g. &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;) and an alarm command (e.g. &amp;lt;code&amp;gt;NMS&amp;lt;/code&amp;gt;, ignore this).&lt;br /&gt;
Here are the possible process commands for an output link:&lt;br /&gt;
* &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; - Just write a value; don't process the target record; this is a default command.&lt;br /&gt;
* &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; - Write a value and then process the target record. To be use if you want EPICS to trace processing (&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;= wait for completion?&amp;lt;/span&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; - Write a value; let the target record decide whether or not to process (as it would if you typed the value by hand); if the processing does occur, EPICS will not trace it. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: &lt;br /&gt;
* The default link process command, &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt;, is '''almost never the desired behavior''' for output links. Change &amp;lt;code&amp;gt;NPP&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;PP&amp;lt;/code&amp;gt; immediately and revert if problems are discovered.&lt;br /&gt;
* If the target PV is itself a link field, you must specify the command &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt;; if you want to wait for completion in this case, you must use either the '''sseq''' or the '''sCalcout''' record, select &amp;lt;code&amp;gt;CA&amp;lt;/code&amp;gt; and set the link's '''WAIT''' field to &amp;lt;code&amp;gt;Wait&amp;lt;/code&amp;gt;&lt;br /&gt;
* ''outlinkHelp'' is accessible from userTransform and scaler screens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Forward Links ====&lt;br /&gt;
&lt;br /&gt;
Forward link look like output links; they are purple on user displays, but they don't auto-populate with process &amp;amp; alarm commands. &lt;br /&gt;
Forward link causes the linked record to process when the record containing the forward link is processed&lt;br /&gt;
* Linked record is in the same IOC ('''PROC''' field for linked record is optional):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
* Linked record is in a different IOC ('''PROC''' field for linked record is required):&lt;br /&gt;
** &amp;lt;code&amp;gt;record_name.FLNK = linked_record_name.PROC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* Forwarding-linking records in the same IOC by only specifying the record name is an exception to the &amp;quot;'''VAL''' ''is the default field''&amp;quot; rule.&lt;br /&gt;
* When omitting the '''PROC''' field of a linked record in a different IOC, nothing will happen but you won't get any error message.&lt;br /&gt;
* Always specify the '''PROC''' field to avoid problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More about records ===&lt;br /&gt;
&lt;br /&gt;
* Records vary significantly in complexity; one way to classify them would be (*):&lt;br /&gt;
** Simple records are associated with individual data types&lt;br /&gt;
*::;bi, bo, mbbi, mbbo, longin, longout, ai, ao, stringin, stringout, waveform&lt;br /&gt;
** Intermediate records often perform calculations or link multiple records&lt;br /&gt;
*::;calcout, scalcout, acalcout, swait, transform, fanout, dfanout&lt;br /&gt;
** Complex records are associated with devices or higher-level functionality&lt;br /&gt;
*::;motor, scaler, mca, sscan, table, digitel, vs&lt;br /&gt;
** Flexible records allow custom functionality to be implemented&lt;br /&gt;
*::;sub, aSub, luascript&lt;br /&gt;
(*) this is not an official classification, nor an exhaustive list of records.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;:&lt;br /&gt;
* areaDetector databases are composed of mostly simple record.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More about record fields ===&lt;br /&gt;
&lt;br /&gt;
To find documentation for a specific field you need to know/find answers to the following questions:&lt;br /&gt;
* Is the field common to all or input/output record types?  &lt;br /&gt;
* If not, does the record come from EPICS base or a different EPICS module (synApps)?&lt;br /&gt;
** The [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation] is the best place to find information about record types that come from EPICS base. &amp;lt;br&amp;gt;Field documentation appears in multiple locations:&lt;br /&gt;
*** Fields common to all record types&lt;br /&gt;
*** Fields common to input record types&lt;br /&gt;
*** Fields common to output record types&lt;br /&gt;
*** Record-specific documentation&lt;br /&gt;
** synApps record reference documentation&lt;br /&gt;
*** In each module's documentation directory&lt;br /&gt;
**** [https://github.com/epics-modules https://github.com/epics-modules]&lt;br /&gt;
**** &amp;lt;code&amp;gt;/APSshare/epics/synApps_X_Y/support&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a databases? ==&lt;br /&gt;
&lt;br /&gt;
A database is just a text file with a '''.db''' (or '''.template''') extension containing a collection of records that are related. &lt;br /&gt;
&lt;br /&gt;
Databases are generalized with macros to allow multiple instances to be loaded (e.g. $(P)):&lt;br /&gt;
* Macros are variables containing strings to be substituted when the database is loaded.&lt;br /&gt;
* Macros without default values are required to load the database; there is no easy way to figure out what those are for a given database other than looking at the file itself.&lt;br /&gt;
* Macros required by the database should match the macros required by associated screens &amp;amp; autosave (.req) files.&lt;br /&gt;
* The P (prefix) macro usually includes a colon (:), which is the standard separator used in PV names.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How are databases loaded? ===&lt;br /&gt;
&lt;br /&gt;
There are 2 ways to load databases which are strictly equivalent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== dbLoadRecords ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam1,PORT=serial1,A=01&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadRecords(&amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;,&amp;quot;P=kmp:,R=adam2,PORT=serial1,A=02&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== dbLoadTemplate ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;dbLoadTemplate(&amp;quot;substitutions/ADAM_4018.substitutions&amp;quot;,&amp;quot;P=kmp:&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ADAM_4018.substitutions:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;file &amp;quot;$(IP)/db/ADAM_4018.db&amp;quot;&lt;br /&gt;
 {&lt;br /&gt;
 pattern&lt;br /&gt;
 {R,PORT,A}&lt;br /&gt;
 {adam1, serial1,01}&lt;br /&gt;
 {adam2, serial1,02}&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is a device? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;What is a device?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How does one create an IOC? ==&lt;br /&gt;
&lt;br /&gt;
There are multiple ways to create an IOC, but no one does it from scratch:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The EPICS base approach ===&lt;br /&gt;
It creates a bare bones IOC but requires more knowledge of the EPICS build system to get started:&lt;br /&gt;
::'''&amp;lt;code&amp;gt;makeBaseApp.pl&amp;lt;/code&amp;gt;'''&lt;br /&gt;
* Must be run multiple times&lt;br /&gt;
* Creates IOC contents in the current directory&lt;br /&gt;
* synApps support needs to be added manually&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The synApps approach ===&lt;br /&gt;
&lt;br /&gt;
It is based on the ''xxx'' module and designed to give you a usable IOC with as little effort as possible:&lt;br /&gt;
::'''&amp;lt;code&amp;gt;mkioc&amp;lt;/code&amp;gt;'''&lt;br /&gt;
 &lt;br /&gt;
* A single command leaves you with an IOC you can build:&lt;br /&gt;
::&amp;lt;code&amp;gt;/APSshare/bin/mkioc -n -f -s 6-2-1 kmp&amp;lt;/code&amp;gt;&lt;br /&gt;
* Creates a top-level IOC directory in the current directory&lt;br /&gt;
* Common synApps support is included by default&lt;br /&gt;
* mkioc will ask you questions if you run it without options&lt;br /&gt;
&lt;br /&gt;
Note: The BCDA convention is to name development IOCs using the developer's initials (here ''kmp'').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IOC Layout ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The IOC layout can be overwhelming and confusing to those who aren’t yet familiar with it. The EPICS build system creates many directories, making it harder to find the important directories.&lt;br /&gt;
Important files are often buried multiple directories down from the top-level. It is helpful to look at subsets of the IOC directory.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;17&amp;quot;; style=&amp;quot;color:blue&amp;quot;|kmp&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|bin&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:red&amp;quot;|rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|configure&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:red&amp;quot;|db&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:red&amp;quot;|dbd&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;4&amp;quot;|iocBoot&lt;br /&gt;
|rowspan=&amp;quot;4&amp;quot;; style=&amp;quot;color:green&amp;quot;|iockmp&lt;br /&gt;
|autosave&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:green&amp;quot;|iocsh&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:blue&amp;quot;| softioc&lt;br /&gt;
| commands&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color:green&amp;quot;| substitutions&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;6&amp;quot;|kmpApp&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|Db&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|op&lt;br /&gt;
|adl&lt;br /&gt;
|-&lt;br /&gt;
|ui&lt;br /&gt;
| autoconvert&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:orange&amp;quot;|src&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.Common&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;; style=&amp;quot;color:grey&amp;quot;|O.rhel8-x86_64&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|lib&lt;br /&gt;
|colspan=&amp;quot;3&amp;quot;; style=&amp;quot;color:red&amp;quot;|rhel8-x86_64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Build configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: orange&amp;quot;&amp;gt;Orange&amp;lt;/span&amp;gt; folders:&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/configure&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the files that specify which versions of EPICS base and EPICS modules should be should be used when building the IOC.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/kmpApp/Db&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains local databases (and associated autosave files) and protocol files used by the IOC.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/kmpApp/src&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the Makefile that determines all of the software that gets built into the IOC binary. ; local sequence programs and other EPICS support that needs to be compiled go here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Intermediate build directories ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: grey&amp;quot;&amp;gt;Grey&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
The EPICS Build system will generate '''&amp;lt;code&amp;gt;O.&amp;lt;/code&amp;gt;''' files (Common, EPICS HOST and TARGET architectures) in the configure, Db, and src directory.  These directories are not needed after the IOC is built and can be removed with the '''&amp;lt;code&amp;gt;make clean&amp;lt;/code&amp;gt;''' command. If they are not removed, they can be safely ignored.  It is highly unlikely that you will ever need to look at any of the files in them.&lt;br /&gt;
&lt;br /&gt;
=== Build products ===&lt;br /&gt;
&lt;br /&gt;
The EPICS build system creates top level bin, db, dbd, and lib directories (&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;red&amp;lt;/span&amp;gt; folders):  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/bin/rehl8-x86_64&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains the architecture-specific IOC binary (or munch file for VxWorks IOCs).  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/db&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains installed database files which may or may not be used, since many IOCs reference the databases in the Db directory instead.  &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/dbd&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains a single database definition file to be loaded by the IOC. &lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmp/lib/rehl8-x86_64&amp;lt;/code&amp;gt;''': &lt;br /&gt;
:contains architecture-specific files for EPICS modules, but should be empty for the IOC.&amp;lt;br&amp;gt;&lt;br /&gt;
The build system creates an envPaths file in the startup directory, which contains the locations of the modules defined in the RELEASE file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Run-time configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;Green&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The iockmp directory is referred to as the ''startup'' directory.  It contains the '''&amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt;''' file, which is the runtime configuration for the IOC &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;what means runtime?&amp;lt;/span&amp;gt;  &lt;br /&gt;
The IOC’s config is often broken into separate '''&amp;lt;code&amp;gt;.iocsh&amp;lt;/code&amp;gt;''' (or '''&amp;lt;code&amp;gt;.cmd&amp;lt;/code&amp;gt;''') files so that support can be more easily commented out and to improve readability.  &lt;br /&gt;
Substitutions and iocsh files usually reside in subdirectories to reduce clutter in the startup directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Start scripts ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Blue&amp;lt;/span&amp;gt; folders: &amp;lt;br&amp;gt;&lt;br /&gt;
The top-level IOC directory contains scripts that start medm/caQtDM.&lt;br /&gt;
The softioc subdirectory of the startup dir contains a bash script which simplifies managing the IOC on Linux.&lt;br /&gt;
Windows IOCs: the startup directory contains batch files to start the IOC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: The startup directory can reside elsewhere.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How does support get into an IOC? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Quick overview ===&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;configure/RELEASE&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** Defines the locations of EPICS base and EPICS modules&lt;br /&gt;
** Often includes other RELEASE files&lt;br /&gt;
* '''&amp;lt;code&amp;gt;kmpApp/src/Makefile&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** Specifies which database definitions (dbd) to include&lt;br /&gt;
** Specifies which libraries should be included in the IOC binary&lt;br /&gt;
** Specifies which local code should be included in the IOC binary&lt;br /&gt;
** Libraries will not be included unless an associated dbd file is included&lt;br /&gt;
** The order of the libraries is important (single-pass linker)&lt;br /&gt;
* '''&amp;lt;code&amp;gt;iocBoot/iockmp/st.cmd&amp;lt;/code&amp;gt;''':&lt;br /&gt;
** The primary IOC config file that is sourced when the IOC is started&lt;br /&gt;
** Name can vary slightly based on how the IOC was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Startup script &amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Legacy IOCs often have monolithic '''&amp;lt;code&amp;gt;st.cmd&amp;lt;/code&amp;gt;''' files. Newer IOCs source more '''&amp;lt;code&amp;gt;.iocsh&amp;lt;/code&amp;gt;''' files from EPICS modules, which makes it easier to keep an IOC's config up-to-date.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt; envPaths&lt;br /&gt;
 &lt;br /&gt;
 dbLoadDatabase(&amp;quot;../../dbd/iockmpLinux.dbd&amp;quot;)&lt;br /&gt;
 iockmpLinux_registerRecordDeviceDriver(pdbbase)&lt;br /&gt;
 &lt;br /&gt;
 ### Databases are loaded&lt;br /&gt;
 ### Drivers are initialized/configured here&lt;br /&gt;
 &lt;br /&gt;
 iocInit&lt;br /&gt;
 &lt;br /&gt;
 ### Sequence programs &amp;amp; autosave are started here&lt;br /&gt;
 &lt;br /&gt;
 dbl &amp;gt; dbl-all.txt&lt;br /&gt;
 &lt;br /&gt;
 date&lt;br /&gt;
&lt;br /&gt;
We can break it up into 3 functional zones:&lt;br /&gt;
* Zone 1: before '''&amp;lt;code&amp;gt;dbLoadDatabase&amp;lt;/code&amp;gt;'''.  Usually this is where env vars and paths are defined.&lt;br /&gt;
* Zone 2: after '''&amp;lt;code&amp;gt;dbLoadDatabase&amp;lt;/code&amp;gt;''' &amp;amp; before '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  Databases can only be loaded here.&lt;br /&gt;
* Zone 3: after '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  This zone is mostly empty thanks to '''&amp;lt;code&amp;gt;doAfterIocInit&amp;lt;/code&amp;gt;''' from the '''&amp;lt;code&amp;gt;std&amp;lt;/code&amp;gt;''' module (sequence programs and autosave get initialized here, but the calls that do the initializing appear much earlier in the startup)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: PVs are available during '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;''', even though the IOC is still starting up.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Autosave ===&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;autosave&amp;lt;/code&amp;gt;''' is a synApps module that provides seamless reboot functionality. It is mostly automatic when '''mkioc''' is used. &lt;br /&gt;
PVs are saved while the IOC is running and loaded during '''&amp;lt;code&amp;gt;iocInit&amp;lt;/code&amp;gt;'''.  &lt;br /&gt;
Autosaved values overwrite database defaults.&lt;br /&gt;
&lt;br /&gt;
Databases with associated req files ('''&amp;lt;code&amp;gt;_settings.req&amp;lt;/code&amp;gt;''') are automatically added to '''&amp;lt;code&amp;gt;built_*.req&amp;lt;/code&amp;gt;''' by autosaveBuild&lt;br /&gt;
Multiple '''&amp;lt;code&amp;gt;.sav&amp;lt;/code&amp;gt;''' files can be created:&lt;br /&gt;
* Default:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav&amp;lt;/code&amp;gt;''' &amp;amp; '''&amp;lt;code&amp;gt;.savB&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** actually restored&lt;br /&gt;
* Periodic:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav0&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;.sav1&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;.sav2&amp;lt;/code&amp;gt;''', …&lt;br /&gt;
** overwritten cyclically&lt;br /&gt;
* Dated:&lt;br /&gt;
** '''&amp;lt;code&amp;gt;.sav-230109-134502&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** written once at boot time&lt;br /&gt;
&lt;br /&gt;
The 1st half of '''&amp;lt;code&amp;gt;common.iocsh&amp;lt;/code&amp;gt;''' sets up autosave:&lt;br /&gt;
[https://github.com/epics-modules/xxx/blob/master/iocBoot/iocxxx/common.iocsh#L1-L46 https://github.com/epics-modules/xxx/blob/master/iocBoot/iocxxx/common.iocsh#L1-L46]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How to build &amp;amp; clean a Linux IOC ===&lt;br /&gt;
&lt;br /&gt;
* Confirm the RHEL version&lt;br /&gt;
** &amp;lt;code&amp;gt; '''uname -r''' → 3.10.0-1160.62.1.'''el7'''.x86_64&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; '''cat /etc/redhat-release''' → Red Hat Enterprise Linux Server release '''7.9'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Set &amp;lt;code&amp;gt; EPICS_HOST_ARCH&amp;lt;/code&amp;gt;  environment variable&lt;br /&gt;
** bash: &amp;lt;code&amp;gt;'''export EPICS_HOST_ARCH=rhel7-x86_64'''&amp;lt;/code&amp;gt;&lt;br /&gt;
** tcsh: &amp;lt;code&amp;gt;'''setenv EPICS_HOST_ARCH rhel7-x86_64'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Initiate the build in the top-level IOC directory&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Remove intermediate build dirs (for the current &amp;lt;code&amp;gt; EPICS_HOST_ARCH&amp;lt;/code&amp;gt; )&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make clean'''&amp;lt;/code&amp;gt; &lt;br /&gt;
* Remove all intermediate build dirs and top-level build directories&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make distclean'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* Show all make options&lt;br /&gt;
** &amp;lt;code&amp;gt;'''make help'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running an IOC ==&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use the script ===&lt;br /&gt;
&lt;br /&gt;
==== Create an alias ====&lt;br /&gt;
&lt;br /&gt;
Create an alias for the script (assuming PWD = IOC’s top-level dir)&lt;br /&gt;
:&amp;lt;code&amp;gt;$ '''alias kmp=${PWD}/iocBoot/iockmp/softioc/kmp.sh'''&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;$ '''kmp''' &amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Usage: kmp.sh {console|restart|run|start|caqtdm|medm|status|stop|usage}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Noteworthy arguments:&lt;br /&gt;
* '''&amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt;''': Runs the IOC in the current terminal (doesn't return the command prompt). Useful for troubleshooting.  Problematic for normal operation.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt;''': Runs the IOC in the background (returns the command prompt) using screen or procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;''': Tells you if the IOC is running and refuses to start if it is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Notes&amp;lt;/u&amp;gt;: &lt;br /&gt;
* Use the full path to the IOC’s start script so the alias can be run from any directory (bash syntax shown).&lt;br /&gt;
* &amp;lt;code&amp;gt;EPICS_HOST_ARCH&amp;lt;/code&amp;gt; needs to still be set otherwise the IOC will not start (unless the &amp;lt;code&amp;gt;EPICS_HOST_ARCH&amp;lt;/code&amp;gt; is hard-coded in the start script)&lt;br /&gt;
* The ampersand is needed for synApps_6_2_1 IOCs, but it won’t be needed in the future because it was added to the '''&amp;lt;code&amp;gt;start_caQtDM_xxx&amp;lt;/code&amp;gt;''' script.&lt;br /&gt;
* Bugs in the deployed copy of '''&amp;lt;code&amp;gt;xxx.sh&amp;lt;/code&amp;gt;''' may prevent it from detecting an IOC is running.&lt;br /&gt;
&lt;br /&gt;
==== Start caQtDM ====&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp caqtdm &amp;amp;&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== Start the IOC ====&lt;br /&gt;
&lt;br /&gt;
Starts the IOC in the background (using screen or procServ):&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp start&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
IOCs are usually run in screen or procServ so that: &lt;br /&gt;
* the window in which they’re started can be closed&lt;br /&gt;
* multiple people can connect to them&lt;br /&gt;
* [procServ] allows other user accounts to restart an IOC&lt;br /&gt;
* [procServ] allows users to connect to Windows IOCs&lt;br /&gt;
&lt;br /&gt;
==== Confirm the IOC is running ====&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;kmp status&amp;lt;/code&amp;gt;'''&lt;br /&gt;
:&amp;lt;code&amp;gt;kmp is running (pid=1281733) in a screen session (pid=1281732)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connecting to an IOC’s shell ===&lt;br /&gt;
&lt;br /&gt;
There are many ways to do it:&lt;br /&gt;
&lt;br /&gt;
* Manually connect to an IOC running in screen from the IOC’s host&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''screen -x kmp'''&amp;lt;/code&amp;gt;&lt;br /&gt;
::The -x option will connect even if someone is already connected to the screen session.  &lt;br /&gt;
::The -r option only succeeds if no one is connected to the session.&lt;br /&gt;
&lt;br /&gt;
* Connect to an IOC running in screen or procServ from the IOC’s host&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''kmp console'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Connect to an IOC running in screen or procServ with logging '''from any host'''&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''/APSshare/bin/iocConsole.py iockmp'''&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;u&amp;gt;Note&amp;lt;/u&amp;gt;: iocConsole.py requires ssh access which beamline accounts don't have by default&lt;br /&gt;
&lt;br /&gt;
* Manually connect to an IOC running in procServ from the IOC’s subnet&lt;br /&gt;
::&amp;lt;code&amp;gt;$ '''telnet s100bcda 53127'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disconnecting from an IOC’s shell ===&lt;br /&gt;
&lt;br /&gt;
* '''Close the terminal''' that is connected to the screen or procServ session&lt;br /&gt;
** Disconnects from both screen &amp;amp; procServ&lt;br /&gt;
** Kills an IOC running outside of screen &amp;amp; procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Ctrl+a&amp;lt;/code&amp;gt;''', '''&amp;lt;code&amp;gt;Ctrl+d&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** Disconnects from both screen &amp;amp; procServ&lt;br /&gt;
** Kills an IOC running outside of screen &amp;amp; procServ&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Ctrl+a, d&amp;lt;/code&amp;gt;'''&lt;br /&gt;
** Only disconnects from screen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== IOC shell commands ===&lt;br /&gt;
&lt;br /&gt;
:'''&amp;lt;code&amp;gt;help [command]&amp;lt;/code&amp;gt;''' - shows available commands or syntax of specified command&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbpr record_name [0-9]&amp;lt;/code&amp;gt;''' - displays fields and values for a given record&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl&amp;lt;/code&amp;gt;''' - lists all records in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl record_type&amp;lt;/code&amp;gt;''' - lists all records of a specific type in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbl record_type &amp;quot;field_list&amp;quot;&amp;lt;/code&amp;gt;''' - lists specified fields (space-separated list) of records of a specific type in an IOC&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbpf pv_name value&amp;lt;/code&amp;gt;''' - change a PV’s value – analogous to caput&lt;br /&gt;
:'''&amp;lt;code&amp;gt;dbgf pv_name&amp;lt;/code&amp;gt;''' - read a PV’s value – analogous to caget&lt;br /&gt;
:'''&amp;lt;code&amp;gt;epicsEnvShow&amp;lt;/code&amp;gt;''' - prints environment variables&lt;br /&gt;
:'''&amp;lt;code&amp;gt;seqShow&amp;lt;/code&amp;gt;''' - shows running sequence programs&lt;br /&gt;
:'''&amp;lt;code&amp;gt;seqStop&amp;lt;/code&amp;gt;''' - stops a running sequence program&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Help:Formatting Help formatting]&lt;br /&gt;
* [https://epics.anl.gov/base/R3-16/2-docs/AppDevGuide/DatabaseDefinition.html#x7-2630006.6 https://epics.anl.gov/]&lt;br /&gt;
* [https://epics.anl.gov/base/R7-0/7-docs/RecordReference.html EPICS base record reference documentation]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=File:EPICS_basics_linking_diagrams.png&amp;diff=270</id>
		<title>File:EPICS basics linking diagrams.png</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=File:EPICS_basics_linking_diagrams.png&amp;diff=270"/>
		<updated>2023-03-08T02:17:00Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Diagram showing runtime and compile time links between IOC applications, modules, and EPICS base.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Diagram showing runtime and compile time links between IOC applications, modules, and EPICS base.&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=File:EPICS_basics_PV_diagram.png&amp;diff=269</id>
		<title>File:EPICS basics PV diagram.png</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=File:EPICS_basics_PV_diagram.png&amp;diff=269"/>
		<updated>2023-03-08T02:16:18Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: Diagram illustrating PVs, databases, records, and fields, as well as distinguishing between IOC applications, modules, and clients.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Diagram illustrating PVs, databases, records, and fields, as well as distinguishing between IOC applications, modules, and clients.&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=24</id>
		<title>Controls Software Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=24"/>
		<updated>2022-12-08T19:54:03Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: add link to troubleshooting page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page exists to collect links to documentation about the instrument control system EPICS, its modules and related libraries (synApps, areaDetector), as used at the Advanced Photon Source.&lt;br /&gt;
&lt;br /&gt;
Documentation referenced should be appropriate for beamline scientists, as opposed to only EPICS developers.&lt;br /&gt;
New deployments should prefer EPICSv7, the latest release series.&lt;br /&gt;
&lt;br /&gt;
See also the extensive [https://epics-controls.org/resources-and-support/documents/training/ resources from past EPICS Collaboration meetings].&lt;br /&gt;
&lt;br /&gt;
==EPICS Base==&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Intro.html Intro to EPICS]&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html EPICS Database Concepts]&lt;br /&gt;
* [https://docs.epics-controls.org/projects/how-tos/en/latest/getting-started/installation.html EPICS Base Getting Started (official)]&lt;br /&gt;
&lt;br /&gt;
==synApps (aka EPICS Support)==&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps_docs_all.html synApps Collected Documentation]&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps.html synApps deployment instructions, including use of xxx template ioc]&lt;br /&gt;
&lt;br /&gt;
==areaDetector==&lt;br /&gt;
* [https://areadetector.github.io/master/index.html areaDetector Official Documentation]&lt;br /&gt;
&lt;br /&gt;
==Deploying, troubleshooting, and maintaining IOCs==&lt;br /&gt;
* [[Troubleshooting EPICS IOCs]]&lt;br /&gt;
* [https://docs2bm.readthedocs.io/en/latest/source/ops/item_000_0.html simDetector Install directions (2BM)]&lt;br /&gt;
* [https://wiki.aps.anl.gov/bcda/index.php?title=The_Basics_of_an_IOC The Basics of an IOC (APS Internal)]&lt;br /&gt;
* [https://gist.github.com/keenanlang/e768774cbd0a367b96281939b8a2c9ba Creation of an IOC using mkioc]&lt;br /&gt;
&lt;br /&gt;
==Maintaining Documentation==&lt;br /&gt;
* [https://bctwg.readthedocs.io/en/latest/index.html ReadTheDocs tutorial and example site]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Troubleshooting_EPICS_IOCs&amp;diff=23</id>
		<title>Troubleshooting EPICS IOCs</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Troubleshooting_EPICS_IOCs&amp;diff=23"/>
		<updated>2022-12-08T19:53:54Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: new page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding the structure of a deployed EPICS IOC and environment, determining configuration, and parsing error messages.&lt;br /&gt;
&lt;br /&gt;
== Linux-specific ==&lt;br /&gt;
&lt;br /&gt;
=== Examine the environment with &amp;lt;code&amp;gt;env&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
EPICS reads several &amp;quot;environment variables&amp;quot; during operation. &lt;br /&gt;
You can examine the current list of environment variables in a terminal (either bash or csh) using &amp;lt;code&amp;gt;env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get the value of a particular environment variable, try&lt;br /&gt;
&amp;lt;code&amp;gt;env | grep VARIABLE&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;echo $VARIABLE &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Particularly relevant ones are:&lt;br /&gt;
&lt;br /&gt;
; PATH : list of folders which are searched for executable scripts and binaries. If you are seeing &amp;quot;command not found&amp;quot;-type errors, consider if $PATH is set correctly.&lt;br /&gt;
; EPICS_CA_ADDR_LIST : IP addresses that are contacted when searching for a CA (channel-access) variable. Important for any program which is accessing CA variables provided by a different program, possibly on a different host.&lt;br /&gt;
; EPICS_CA_AUTO_ADDR_LIST : (yes | no). Whether to also include the broadcast address for all configured network interfaces in the CA_ADDR_LIST. This automatically searches all computers on the same subnet for variables.&lt;br /&gt;
; EPICS_PVA_ADDR_LIST : As above, but for PVaccess variables.&lt;br /&gt;
; EPICS_PVA_AUTO_ADDR_LIST : As above, but for automatic use of broadcast addresses for PVaccess variables.&lt;br /&gt;
&lt;br /&gt;
For example, when examining a GUI which should only connect to the channel access variables of a local instance of an IOC, you might expect to see a configuration like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;EPICS_CA_AUTO_ADDR_LIST=no&lt;br /&gt;
EPICS_CA_ADDR_LIST=127.0.0.255&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Find library dependencies with ldd ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is necessary to determine which versions of a shared library are linked into the IOC binary. On other occasions, an IOC binary will not run (typically, an immediate segfault) because a necessary linked library is missing.&lt;br /&gt;
&amp;lt;code&amp;gt;ldd&amp;lt;/code&amp;gt; is a Linux tool which will list all linked dynamic (shared) libraries of a binary, to answer these questions. Execute &amp;lt;code&amp;gt;ldd -r&amp;lt;/code&amp;gt; against the IOC '''binary''' (not startup script) and examine its output.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cd ~/epics/synApps_6_2_1/ioc/IocSpinnaker/&lt;br /&gt;
$ ldd -r bin/rhel8-x86_64/SpinnakerApp&lt;br /&gt;
      linux-vdso.so.1 (0x00007ffffb195000)&lt;br /&gt;
      libADSpinnaker.so =&amp;gt; /net/s100dserv/APSshare/epics/synApps_6_2_1/support/areaDetector-R3-12-1/ADSpinnaker/lib/rhel8-x86_64/libADSpinnaker.so (0x00007f149e6f9000)&lt;br /&gt;
      libADGenICam.so =&amp;gt; /net/s100dserv/APSshare/epics/synApps_6_2_1/support/areaDetector-R3-12-1/ADGenICam/lib/rhel8-x86_64/libADGenICam.so (0x00007f149e4e6000)&lt;br /&gt;
      ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The location of all found libraries will be listed in full, while any missing libraries will be noted:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      libfoo.so =&amp;gt; not found&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View the full IOC output when running in screen ===&lt;br /&gt;
&lt;br /&gt;
By default, IOCs built from the XXX template are controlled via a startup shell script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ExampleIOC.sh (start|stop|status)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you start an IOC this way, no output is immediately visible, and control returns to your terminal. It is possible to connect to the IOC console via&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ExampleIOC.sh console&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which opens a connection to &amp;lt;code&amp;gt;screen&amp;lt;/code&amp;gt;, the Linux terminal multiplexer. Type &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt; at the IOC prompt to exit, or use &amp;lt;code&amp;gt;Ctrl-a Ctrl-d&amp;lt;/code&amp;gt; (detach) to leave the IOC running in the background and return to the terminal. &amp;lt;code&amp;gt;Ctrl-a [&amp;lt;/code&amp;gt; will change screen to scrollback-mode, where you will be able to examine the stored history of IOC output. Use &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; to search forward through the text, and &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt; to search backwards, for example to find errors.&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
	<entry>
		<id>https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=22</id>
		<title>Controls Software Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki-ext.aps.anl.gov/blc/index.php?title=Controls_Software_Documentation&amp;diff=22"/>
		<updated>2022-11-07T21:05:34Z</updated>

		<summary type="html">&lt;p&gt;Tguruswamy: /* synApps (support) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page exists to collect links to documentation about the instrument control system EPICS, its modules and related libraries (synApps, areaDetector), as used at the Advanced Photon Source.&lt;br /&gt;
&lt;br /&gt;
Documentation referenced should be appropriate for beamline scientists, as opposed to only EPICS developers.&lt;br /&gt;
New deployments should prefer EPICSv7, the latest release series.&lt;br /&gt;
&lt;br /&gt;
See also the extensive [https://epics-controls.org/resources-and-support/documents/training/ resources from past EPICS Collaboration meetings].&lt;br /&gt;
&lt;br /&gt;
==EPICS Base==&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Intro.html Intro to EPICS]&lt;br /&gt;
* [https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html EPICS Database Concepts]&lt;br /&gt;
* [https://docs.epics-controls.org/projects/how-tos/en/latest/getting-started/installation.html EPICS Base Getting Started (official)]&lt;br /&gt;
&lt;br /&gt;
==synApps (aka EPICS Support)==&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps_docs_all.html synApps Collected Documentation]&lt;br /&gt;
* [https://epics.anl.gov/bcda/synApps/synApps.html synApps deployment instructions, including use of xxx template ioc]&lt;br /&gt;
&lt;br /&gt;
==areaDetector==&lt;br /&gt;
* [https://areadetector.github.io/master/index.html areaDetector Official Documentation]&lt;br /&gt;
&lt;br /&gt;
==Deploying and maintaining IOCs==&lt;br /&gt;
* [https://docs2bm.readthedocs.io/en/latest/source/ops/item_000_0.html simDetector Install directions (2BM)]&lt;br /&gt;
* [https://wiki.aps.anl.gov/bcda/index.php?title=The_Basics_of_an_IOC The Basics of an IOC (APS Internal)]&lt;br /&gt;
* [https://gist.github.com/keenanlang/e768774cbd0a367b96281939b8a2c9ba Creation of an IOC using mkioc]&lt;br /&gt;
&lt;br /&gt;
==Maintaining Documentation==&lt;br /&gt;
* [https://bctwg.readthedocs.io/en/latest/index.html ReadTheDocs tutorial and example site]&lt;/div&gt;</summary>
		<author><name>Tguruswamy</name></author>
	</entry>
</feed>