.. _rpi_epics: Installing EPICS on RaspberryPi =============================== .. caution: work-in-progress :date: 2020-04-10 :RPi models: any (but older ones are much slower) :requirements: 16GB SD card (micro for most models), networking :Raspberry Pi OS: Raspbian Buster :optional: display, keyboard, mouse (only needed for initial setup) :shell: ``/bin/bash`` This document is an update to http://prjemian.github.io/epicspi/ .. sidebar:: What is EPICS? For those who haven’t heard, EPICS (https://epics.anl.gov) is an open-source control system used worldwide for the routine operation and control of many particle accelerators such as FermiLab and SLAC, for the operation of scientific telescopes such as the Gemini and Keck telescopes, X-ray synchrotrons such as the Advanced Photon Source and the Diamond Light Source, neutron diffraction facilities such as the Spallation Neutron Source, and lots of other neat stuff. The system is scalable and runs on lots of different hardware. Here, we show you how to run EPICS on the Raspberry Pi! Overview -------- Here is how I installed the Experimental Physics and Industrial Control System software `EPICS `__ on the `Raspberry Pi `__. The EPICS software is a client/server system. To keep things simple, we will run both the server and a client on the Raspberry Pi. (Clients on other computers on our LAN can interact with our EPICS server but we will not discuss that now.) The EPICS **server** we will use is built in several parts: - `EPICS Base `__ provides all the development libraries and a few applications and utilities. - `EPICS synApps `__ provides additional capabilities that will be useful in real projects. We only use a little of it here, though. There are many, many possible EPICS **clients**. Since the RPi already has Python, we’ll work with that: - `PyEpics `__ is an EPICS binding to the Python language, allowing us to build a simple client and interact with our server. Prepare the RaspberryPi (RPi) ----------------------------- 1. OS: download latest OS image from one of the `Raspbian Mirrors `__ 2. flash the OS to a 16GB microSD card using `Balena Etcher `__ (or some other tool) 3. prepare the RPi 4. boot the RPi and configure it for networking on your LAN 5. update the OS per instructions 6. enable SSH access (via ``sudo raspi-config`` or GUI tool) touchscreen rotation ~~~~~~~~~~~~~~~~~~~~ If you have the 7-inch touchscreen for your RPi, then you might want to rotate the display. Following `advice `__ 1. Open the Terminal screen. 2. Access the config file using ``sudo nano /boot/config.txt`` 3. Enter a new line with the text ``lcd_rotate=2`` 4. Press CONTROL+X then Y then ENTER to Save 5. Type ``sudo reboot`` to reboot and your LCD will be rotated! For me, I paste these lines into the end of ``/boot/config.txt``: :: #-------------------------- # 7" touch display screen rotation # default # lcd_rotate=0 # rotate 90 degrees clockwise # lcd_rotate=3 # rotate 180 degrees lcd_rotate=2 # rotate 90 degrees counter clockwise # lcd_rotate=1 Install packages to build & manage EPICS ---------------------------------------- Here we describe how to install libraries, support packages, and other tools to make it easier to manage an EPICS installation. The *raspbian-buster* desktop distribution already has all the tools necessary to build *EPICS Base*. We’ll need additional libraries to compile `EPICS synApps `__ and `EPICS area detector `__. The `Microsoft Visual Studio Code editor `__ is a great tool to have on hand. Really nice people have made it available for the RPi. additional libraries for EPICS synApps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To build the *sequencer* module, the following package must be installed. The *sequencer* module provides *State Notation Language*, a C-like language to provide programming used by other *synApps* modules. :: sudo apt-get install re2c # you _might_ already have these installed, but to be sure... sudo apt-get install libnet-dev libpcap-dev libusb-1.0-0-dev additional libraries for EPICS area detector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These packages must be added to build *GraphicsMagick* for *EPICS area detector*. :: sudo apt install libx11-dev libxext-dev **NOTE** To learn about specific build requirements such as GraphicsMagick, it was useful to search `Debian `__ for the package `details `__ which are specific to the arm architecture of the RPi. Add logmake to .bash_aliases ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When I run ``make`` to compile software, it is convenient to write any/all console output, including errors, to a file for later review. I add this function definition my ``~/.bash_aliases`` file so it is always available: :: function logmake { echo '#-----------------------------------------' >> makelog.txt date >> makelog.txt echo '#begin CMD: make' $@ >> makelog.txt make $@ 2>&1 >> makelog.txt echo '#done CMD: make' $@ >> makelog.txt date >> makelog.txt } It also records time stamps so you can see how long the operation took. It passes any command line arguments to the ``make`` command so you can use it for ``logmake &`` or ``logmake rebuild &`` or ``logmake clean &`` or … Install Microsoft Visual Studio Code editor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: This is optional, performance can be less than anticipated. Following web `guidance `__, both these installers worked for me (on separate RPi computers, of course). one-step installer ^^^^^^^^^^^^^^^^^^ :: curl -L https://raw.githubusercontent.com/headmelted/codebuilds/master/docs/installers/apt.sh | sudo bash two-step installer ^^^^^^^^^^^^^^^^^^ Install GPG keys: :: wget https://packagecloud.io/headmelted/codebuilds/gpgkey -O - | sudo apt-key add - Install Visual Studio Code editor :: curl -L https://raw.githubusercontent.com/headmelted/codebuilds/master/docs/installers/apt.sh | sudo bash Run *code* ^^^^^^^^^^ Once installed, start *code* with either: - desktop GUI: *Accessories* -> **Code-OSS** - terminal command line: ``code-oss`` Preparing for EPICS ------------------- EPICS is flexible about where (into which directory path) it is placed. Still, it helps to use standard locations. We’ll build it in a directory called ``/usr/local/epics`` as user ``pi``. You’ll need to open a terminal window: :: sudo mkdir /usr/local/epics sudo chown pi:pi /usr/local/epics cd /usr/local/epics By making the *epics* directory in ``pi`` account, we will be able to modify any of our EPICS resources without needing to gain higher privileges. Install EPICS base ------------------ *EPICS Base* is very easy to build. All that is necessary is to define the host architecture (in ``EPICS_HOST_ARCH``, shown below) and then build it. First, download the source. At this writing, the latest stable version of `EPICS Base `__ is 7.0.3.1: :: cd /usr/local/epics wget http://www.aps.anl.gov/epics/download/base/base-7.0.3.1.tar.gz tar xzf base-7.0.3.1.tar.gz # for convenience, make a soft link ln -s ./base-7.0.3.1 ./base Make these definitions *before* you build: :: export EPICS_ROOT=/usr/local/epics export EPICS_BASE=${EPICS_ROOT}/base export EPICS_HOST_ARCH=`${EPICS_BASE}/startup/EpicsHostArch` export PATH=${PATH}:${EPICS_BASE}/bin/${EPICS_HOST_ARCH} # and for good measure (might not be needed) export PATH=${PATH}:${EPICS_BASE}/lib/${EPICS_HOST_ARCH} We can check this value by printing it to the command-line: :: pi@raspberrypi:/usr/local/epics $ echo $EPICS_HOST_ARCH linux-arm I make sure they are defined in my ``~/.bash_aliases`` file so they are always defined when I start a command line. Adding to ``PATH`` puts standard EPICS tools on the command line, such as: ``caget``, ``caput``, ``cainfo``, ``camonitor``, ``softIoc`` Next, compile EPICS base (write the build output, including any errors, to a file using `logmake <#add-logmake-to-bashaliase>`__). If you have a multi-CPU RPi, you can use more than one CPU to run make. (Careful! If you try this with older models, such as the RPi A, it will just as likely force an automatic system crash.) My Raspberry Pi 2 Model B v1.1 has four CPUs. Experience guides me to not use more than 2, so I use ``logmake -j2 &``. My Raspberry Pi Zero W has one CPU. With this guide, I show the single CPU build: :: cd /usr/local/epics/base logmake & tail -f makelog.txt This process took different times on different RPi models (and ``make`` options) as shown: ================ ======= ============= ========================================== model options time, minutes ``grep "model name" /proc/cpuinfo`` ================ ======= ============= ========================================== Model 4 B 4GB ``-j2`` 18 ``ARMv7 Processor rev 4 (v7l)`` Model 4 B 4GB 32 ``ARMv7 Processor rev 4 (v7l)`` Model 3 B ``-j2`` 34 ``ARMv7 Processor rev 4 (v7l)`` 2 Model B v1.1 ``-j2`` 64 ``ARMv7 Processor rev 4 (v7l)`` 2 Model B v1.1 110 ``ARMv7 Processor rev 4 (v7l)`` Zero W 266 ``ARMv6-compatible processor rev 7 (v6l)`` ================ ======= ============= ========================================== (For comparison, this same process to build the same version of EPICS base on a linux-x86_64 host with 8 cores at 1.6HGz/3.1GHz using ``logmake -j4 &`` took about 3 minutes.) Wikipedia has a table describing the different RPi hardware: https://en.wikipedia.org/wiki/Raspberry_Pi#Generations_of_released_models Install synApps --------------- Use the guidance from `synApps/support `__ to install the source code for synApps. A new feature is the ability to name the directory into which the source code will be installed. We’ll set that here and include both synApps and base version in the name (in case we change either): :: cd /usr/local/epics export SYNAPPS_DIR=synApps_6.1__base.7.0.3.1 wget https://raw.githubusercontent.com/EPICS-synApps/support/master/assemble_synApps.sh Next, edit the file you just downloaded (``assemble_synApps.sh``) for your version of EPICS base and local directory paths. You can comment out any modules that are not obviously related to execution on the RPi (such as the VME modules: *softGlue*, *softGlueZync*, *VME*, and perhaps others) .. raw:: html
first part of my assemble_synApps.sh file: **CAUTION**: This is guidance! Version numbers (even entire modules) may have changed since this was written so please do not copy this verbatim. :: #not Rpi#ALLENBRADLEY=2.3 #APS only#ALIVE=R1-1-1 AREA_DETECTOR=master ASYN=R4-37 AUTOSAVE=R5-10 BUSY=R1-7-2 CALC=R3-7-3 #not Rpi#CAMAC=R2-7-1 CAPUTRECORDER=R1-7-2 #not Rpi#DAC128V=R2-9 #not Rpi#DELAYGEN=R1-2-1 #not Rpi#DXP=R6-0 #not Rpi#DXPSITORO=R1-2 DEVIOCSTATS=3.1.16 #ETHERIP=ether_ip-3-1 #GALIL=V3-6 IP=R2-20-1 IPAC=2.15 #not Rpi#IP330=R2-9 #not Rpi#IPUNIDIG=R2-11 #not Rpi#LOVE=R3-2-7 LUA=R2-0 MCA=R7-8 #not Rpi#MEASCOMP=R2-3 MODBUS=R3-0 MOTOR=R7-1 OPTICS=R2-13-3 #not Rpi#QUADEM=R9-2-1 SNCSEQ=2.2.6 #not Rpi#SOFTGLUE=R2-8-2 #not Rpi#SOFTGLUEZYNQ=R2-0-2 SSCAN=R2-11-3 STD=R3-6 STREAM=2.8.9 #not Rpi#VAC=R1-9 #not Rpi#VME=R2-9-2 #not Rpi#YOKOGAWA_DAS=R2-0-1 XXX=R6-1 Edit the location of EPICS_BASE (on or near line 34). :: EPICS_BASE=/usr/local/epics/base-7.0.3.1 The rest of that file remains untouched. .. raw:: html
Then, download and install the chosen synApps modules :: cd /usr/local/epics bash ./assemble_synApps.sh Next, build *synApps*: :: cd /usr/local/epics/${SYNAPPS_DIR}/support logmake & tail -f makelog.txt This process took different times on different RPi models as shown: ============== ======= ============= ========================================== model options time, minutes ``grep "model name" /proc/cpuinfo`` ============== ======= ============= ========================================== Model 4 B 4GB ``-j2`` 21 ``ARMv7 Processor rev 4 (v7l)`` Model 3 B ``-j2`` 40 ``ARMv7 Processor rev 4 (v7l)`` 2 Model B v1.1 ``-j2`` TODO ``ARMv7 Processor rev 4 (v7l)`` Zero W 283 ``ARMv6-compatible processor rev 7 (v6l)`` ============== ======= ============= ========================================== (For comparison, this same process to build the same version of EPICS base on a linux-x86_64 host with 8 cores at 1.6HGz/3.1GHz using ``logmake -j4 &`` took about 3 minutes.) Install PyEpics --------------- It is possible to install & run the `PyEpics `__ support from Matt Newville on the Raspberry Pi! :: sudo pip3 install pyepics .. TODO: What about ``libca`` and ``libCom``? Test PyEpics - the EPICS interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Test** that PyEpics is available with this command. Here are my results: :: pi@raspberrypi:~ $ python3 -c "import epics; print(epics.__version__, epics.__file__)" 3.4.1 /usr/local/lib/python3.7/dist-packages/epics/__init__.py To test that PyEpics actually talks with an EPICS IOC, we need to first establish an IOC (EPICS server). We’ll use the *softIoc* executable from EPICS base. create EPICS database ^^^^^^^^^^^^^^^^^^^^^ First, create an EPICS database file ``simple.db``. An EPICS database file is a plain text file that defines the process variables to be available from the IOC. :: cat < simple.db record(bo, "rpi:trigger") { field(DESC, "trigger PV") field(ZNAM, "off") field(ONAM, "on") } record(stringout, "rpi:message") { field(DESC, "message on the RPi") field(VAL, "RPi default message") } EOF **NOTE** The file ``simple.db`` defines two EPICS records: ``rpi:trigger`` and ``rpi:message``. The first record can take the value of ``0`` or ``1``, which also have the string values of ``off`` and ``on``, respectively. The second record is text for a readable message. start EPICS IOC ^^^^^^^^^^^^^^^ Next, run the EPICS soft IOC support with this database: :: pi@raspberrypi:~ $ softIoc -d simple.db dbLoadDatabase("/usr/local/epics/base-7.0.3.1/bin/linux-arm/../../dbd/softIoc.dbd") softIoc_registerRecordDeviceDriver(pdbbase) dbLoadRecords("simple.db") iocInit() Starting iocInit ############################################################################ ## EPICS R7.0.3.1 ## EPICS Base built Feb 21 2020 ############################################################################ iocRun: All initialization complete epics> monitor EPICS PVs ^^^^^^^^^^^^^^^^^ We’ll watch the EPICS process variables (PVs) for any changes in their values using ``camonitor``, an executable from EPICS base. Open a separate terminal window, and enter the ``camonitor`` command below: :: pi@raspberrypi:~ $ camonitor rpi:trigger rpi:trigger.DESC rpi:message rpi:message.DESC rpi:trigger off UDF INVALID rpi:trigger.DESC trigger PV UDF INVALID rpi:message RPi default message UDF NO_ALARM rpi:message.DESC message on the RPi UDF NO_ALARM PyEpics program to write the PVs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Next, in a new terminal, we write a short PyEpics program, ``test.py``, to communicate with the PVs of the softIoc. :: cat < test.py #!/usr/bin/env python3 import epics print(epics.caget('rpi:trigger.DESC')) print(epics.caget('rpi:trigger')) print(epics.caget('rpi:message.DESC')) print(epics.caget('rpi:message')) epics.caput('rpi:message', 'setting trigger') epics.caput('rpi:trigger', 1) print(epics.caget('rpi:trigger.DESC')) print(epics.caget('rpi:trigger')) print(epics.caget('rpi:message.DESC')) print(epics.caget('rpi:message')) epics.caput('rpi:message', 'clearing trigger') epics.caput('rpi:trigger', 0) print(epics.caget('rpi:trigger.DESC')) print(epics.caget('rpi:trigger')) print(epics.caget('rpi:message.DESC')) print(epics.caget('rpi:message')) EOF Make that python program executable: :: chmod +x test.py Next, run that python program: :: pi@raspberrypi:~ $ ./test.py trigger PV 0 message on the RPi RPi default message trigger PV 1 message on the RPi setting trigger trigger PV 0 message on the RPi clearing trigger Note these new messages printed on the terminal running ``camonitor``: :: rpi:message 2020-04-11 13:55:37.454539 setting trigger rpi:trigger 2020-04-11 13:55:37.455587 on rpi:message 2020-04-11 13:55:37.462112 clearing trigger rpi:trigger 2020-04-11 13:55:37.463091 off Delimiters: Parentheses, Braces, and Back-Quotes ------------------------------------------------ In the code examples above, a combination of parentheses, braces, and back-quotes (a.k.a. accent grave or backtick) are used. In the ``/bin/bash`` shell, braces, ``{`` and ``}``, are used to delimit the scope of symbol names during shell expansion. In the code examples above, the delimiters are probably unnecessary. Using these delimiters is a cautious practice to adopt. Parentheses are not recognized in this context: :: ~$ echo $EPICS_ROOT /usr/local/epics ~$ echo ${EPICS_ROOT} /usr/local/epics ~$ echo $(EPICS_ROOT) EPICS_ROOT: command not found However, in the various files and commands that configure and command the EPICS components, parentheses, ``(`` and ``)``, are the required delimiters. See these examples from above: :: #AREA_DETECTOR=$(SUPPORT)/areaDetector-1-8beta1 #IP=$(SUPPORT)/ip-2-13 Sometimes, in a shell script, it is necessary to assign a variable with the value obtained from a command line tool. One common way to do that, shared by ``bash`` and some other shells such as ``tcsh``, is to enclose the command line tool with the ``\``` back-quote character. See this example: :: ~$ echo $SHELL /bin/bash ~$ echo `/usr/local/epics/base-3.14.12.3/startup/EpicsHostArch` linux-x86_64 An alternative way to do this assignment in ``bash`` was pointed out, to use shell expansion with parentheses as the delimiters, such as: :: ~$ echo $(/usr/local/epics/base-3.14.12.3/startup/EpicsHostArch) linux-x86_64 References ---------- Software ~~~~~~~~ ===================== ================================== software URL ===================== ================================== Balena Etcher https://www.balena.io/etcher EPICS https://epics.anl.gov/ EPICS area detector https://cars9.uchicago.edu/software/epics/areaDetector.html EPICS synApps https://www.aps.anl.gov/BCDA/synApps PyEpics https://cars9.uchicago.edu/software/python/pyepics3/ Raspbian OS https://www.raspbian.org Raspbian OS Mirrors https://www.raspbian.org Raspberry Pi https://www.raspberrypi.org VSCode https://pimylifeup.com/raspberry-pi-visual-studio-code/ Touchscreen rotation https://raspberrypiprojects.com/raspberry-pi-rotate-touch-screen/ ===================== ================================== Hardware ~~~~~~~~ References for the Raspberry Pi models shown above: ============== ================= hardware URL ============== ================= Model 4 B 4GB https://www.raspberrypi.org/products/raspberry-pi-4-model-b/ Model 3 B https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ 2 Model B v1.1 https://www.raspberrypi.org/products/raspberry-pi-2-model-b/ Zero W https://www.raspberrypi.org/products/raspberry-pi-zero-w/ Wikipedia https://en.wikipedia.org/wiki/Raspberry_Pi#Generations_of_released_models ============== ================= Facilities ~~~~~~~~~~ These facilities are some of the many that use EPICS (https://epics-controls.org/): ============================== =================== EPICS facility URL ============================== =================== Advanced Photon Source https://www.aps.anl.gov Diamond Light Source https://diamond.ac.uk FermiLab https://fnal.gov Gemini telescope https://gemini.edu Keck telescope https://keckobservatory.org SLAC https://slac.standford.edu Spallation Neutron Source https://neutrons.ornl.gov/sns ============================== ===================