- IOC Deployment and Troubleshooting
- 4 Deploy the motorVMC (Virtual Motor Controller) module
- 4.1 Clone motorVMC
- 4.2 Confirm directories exist
- 4.3 Build motorVMC (Attempt #1)
- 4.4 Resolve build error #1
- 4.5 Build motorVMC (Attempt #2)
- 4.6 Resolve build error #2
- 4.7 Build motorVMC
- 4.8 Confirm build products exist
- 5 Add virtual motors to the IOC
IOC Deployment and Troubleshooting
[previous section] [next section]
4 Deploy the motorVMC (Virtual Motor Controller) module
A Virtual Motor Controller (VMC) has a number of advantages over simulated motors for EPICS trainings:
- It isn't included in xxx-based IOCs by default (motorVMC is not included in the motor module)
- The Virtual Motor Controller can be started/stopped independently of the IOC
- The IOC talks to the Virtual Motor Controller via ethernet
4.1 Clone motorVMC
$ cd ${SUPPORT_DIR}
$ git clone https://git.aps.anl.gov/practical_beamline_controls_training/session_2/motorVMC.git
output
Cloning into 'motorVMC'...
remote: Enumerating objects: 69, done.
remote: Counting objects: 100% (69/69), done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 69 (delta 7), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (69/69), 27.55 KiB | 972.00 KiB/s, done.
Resolving deltas: 100% (7/7), done.
4.2 Confirm directories exist
$ cd motorVMC
$ tree -d .
output
.
├── configure
├── iocs
│ └── vmcIOC
│ ├── configure
│ ├── iocBoot
│ │ └── iocvmc
│ └── vmcApp
│ ├── Db
│ └── src
├── python
└── vmcApp
├── Db
└── src
13 directories
4.3 Build motorVMC (Attempt #1)
$ make
output
configure/RULES_TOP:2: /configure/RULES_TOP: No such file or directory
make: *** No rule to make target '/configure/RULES_TOP'. Stop.
4.4 Resolve build error #1
This build error occurs for the same reason the build error occurred in step 2.4: EPICS_BASE
isn't defined.
The error was much more helpful in step 2.4 because xxx's CONFIG file prints the user friendly error message. The motorVMC developer should add a similar check to the motorVMC module.
hint
The motorVMC/README.md file indicates: "The definitions of MOTOR
and EPICS_BASE
need to be corrected in motorVMC/configure/RELEASE
before motorVMC can be built."
The motorVMC/configure/RELEASE file doesn't contain any definitions, but it does include other files if they exist.
solution
$ cp -p configure/EXAMPLE_RELEASE.local configure/RELEASE.local
The RELEASE.local file contains two variables that need be defined: MOTOR
and MOTOR_VMC
MOTOR
should be set to the same path that is in the envPaths file:
$ grep MOTOR ${IOC_DIR}/xxx/iocBoot/iocxxx/envPaths
epicsEnvSet("MOTOR","/APSshare/epics/synApps_6_2_1/support/motor-R7-2-2")
epicsEnvSet("MOTOR_ACSMOTION","/APSshare/epics/synApps_6_2_1/support/motorAcsMotion-R2-0-bugfix")
MOTOR_VMC
should be set to the present working directory
$ pwd
/home/beams/USERNAME/PET-S2/epics/synApps/support/motorVMC
The result should look like this:
$ cat configure/RELEASE.local
MOTOR=/APSshare/epics/synApps_6_2_1/support/motor-R7-2-2
-include $(MOTOR)/modules/RELEASE.$(EPICS_HOST_ARCH).local
# path to motorVMC is needed to build the IOC inside motorVMC, but outside motor
MOTOR_VMC=/home/beams/USERNAME/PET-S2/epics/synApps/support/motorVMC
where is EPICS_BASE defined?
The EPICS_BASE
variable is not explicitly defined: it is defined in the motor
configuration file that is included with on line 2 of the configure/RELEASE.local
file -include $(MOTOR)/modules/RELEASE.$(EPICS_HOST_ARCH).local
:
$ cat ${MOTOR}/modules/RELEASE.${EPICS_HOST_ARCH}.local
MOTOR = /net/aquila/export/APSmaster/gateway/epics/synApps_6_2_1/support/motor-R7-2-2
ASYN = /APSshare/epics/synApps_6_2_1/support/asyn-R4-42
SNCSEQ = /APSshare/epics/synApps_6_2_1/support/seq-2-2-9
BUSY = /APSshare/epics/synApps_6_2_1/support/busy-R1-7-3
IPAC = /APSshare/epics/synApps_6_2_1/support/ipac-2-16
LUA = /APSshare/epics/synApps_6_2_1/support/lua-R3-0-2
EPICS_BASE = /APSshare/epics/base-7.0.4.1
SUPPORT = /APSshare/epics/synApps_6_2_1/support
what is the difference between RELEASE and RELEASE.local?
In the motorVMC module's configure folder, the presence of two RELEASE files, RELEASE and RELEASE.local, allows for two levels of configuration that can be applied when building the IOC. Here's the difference between the two:
-
RELEASE file: The RELEASE file contains the default configuration for the motorVMC module. It specifies the paths to external support modules or libraries required by the motorVMC module. This file provides a standard configuration that is used by default when building the IOC.
-
RELEASE.local file: The RELEASE.local file is intended for local customization of the configuration. It allows you to override or modify the default configuration specified in the RELEASE file. By including the RELEASE.local file in the configure/RELEASE file, you can provide additional or alternative configuration settings specific to your local environment or requirements.
what is the difference between "building inside motor" and "building outside motor"?
The RELEASE file contains the following:
$ cat configure/RELEASE
# RELEASE - Location of external support modules
# Use motor/module's generated release file when buidling inside motor
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
# Use motorVMC's RELEASE.local when building outside motor
-include $(TOP)/configure/RELEASE.local
"building inside motor" and "building outside motor" refer to different scenarios for compiling or building the IOC.
-
Building inside motor: When building inside motor, it implies that you are within the motor module's directory structure. The
$(TOP)
variable represents the top-level directory of the motor module. In this case, the IOC is being built as part of the motor module itself. The line-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
is included in the configure/RELEASE file. This line instructs the build system to include the generated release file from the motor module. The release file contains configuration information specific to the motor module, such as paths to external support modules or libraries. -
Building outside motor: When building outside motor, it means you are not within the motor module's directory structure. It implies that you are building the IOC separately from the motor module: the
make
command is issued in the ${SUPPORT_DIR}/motorVMC directory. In this case, the line-include $(TOP)/configure/RELEASE.local
is included in the configure/RELEASE file. This line instructs the build system to include the RELEASE.local file from the motorVMC module. The RELEASE.local file typically contains configuration information specific to the IOC being built outside the motor module.
4.5 Build motorVMC (Attempt #2)
If the following build succeeds, proceed to step 4.8.
$ make
output
make -C ./configure install
make[1]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps/support/motorVMC/configure'
perl -CSD /APSshare/epics/base-7.0.4.1/bin/rhel8-x86_64/makeMakefile.pl O.rhel8-x86_64 ../..
mkdir -p O.Common
make -C O.rhel8-x86_64 -f ../Makefile TOP=../.. \
T_A=rhel8-x86_64 install
make[2]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps/support/motorVMC/configure/O.rhel8-x86_64'
perl -CSD /APSshare/epics/base-7.0.4.1/bin/rhel8-x86_64/convertRelease.pl checkRelease
Definition of MOTOR conflicts with SUPPORT support.
In this application or module, a RELEASE file
conflicts with SUPPORT at /APSshare/epics/synApps_6_2_1/support
Here: MOTOR = /net/aquila/export/APSmaster/gateway/epics/synApps_6_2_1/support/motor-R7-2-2
SUPPORT: MOTOR = /APSshare/epics/synApps_6_2_1/support/motor-R7-2-2
make[2]: *** [/APSshare/epics/base-7.0.4.1/configure/RULES_BUILD:190: checkRelease] Error 1
make[2]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps/support/motorVMC/configure/O.rhel8-x86_64'
make[1]: *** [/APSshare/epics/base-7.0.4.1/configure/RULES_ARCHS:58: install.rhel8-x86_64] Error 2
make[1]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps/support/motorVMC/configure'
make: *** [/APSshare/epics/base-7.0.4.1/configure/RULES_DIRS:85: configure.install] Error 2
Note: this build error occurs when there is a mismatch (hard mount vs soft link)
between the /APSshare mount on the computer that built the support on /APSshare
and the computer building the IOC. The two MOTOR
paths actually point to the same
directory.
4.6 Resolve build error #2
The configure/CONFIG_SITE is where the checkRelease behavior is defined.
The CHECK_RELEASE
variable can be overridden to ignore this error.
hint
$ grep RELEASE configure/CONFIG_SITE
# CHECK_RELEASE controls the consistency checking of the support
# applications pointed to by the RELEASE* files.
# Normally CHECK_RELEASE should be set to YES.
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
CHECK_RELEASE = YES
$ tail -n 6 configure/CONFIG_SITE
# These allow developers to override the CONFIG_SITE variable
# settings without having to modify the configure/CONFIG_SITE
# file itself.
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local
solution
$ echo "CHECK_RELEASE = NO" > configure/CONFIG_SITE.local
what does this mean
The error message indicates a conflict between the MOTOR
definition in the
RELEASE.local file and the SUPPORT
support directory because of the
mounting configuration or symbolic links between different machines.
To resolve this error, you can modify the CHECK_RELEASE
setting to either NO
or WARN
in the configure/CONFIG_SITE file. This will disable or allow the build
to continue despite the inconsistency detected. However, please note that it's
important to ensure the paths in the RELEASE* files accurately reflect the correct
locations of the support applications to avoid potential issues during runtime.
Just like the RELEASE.local file, the CONFIG_SITE.local file allows for local
customization of the build configuration. The lines
-include $(TOP)/../CONFIG_SITE.local
and -include $(TOP)/configure/CONFIG_SITE.local
in the configure/CONFIG_SITE file instruct the build system to include the
CONFIG_SITE.local files if they exist in the specified locations. The $(TOP)
variable represents the top-level directory of the IOC.
Note: the linux command $ echo "CHECK_RELEASE = NO" > configure/CONFIG_SITE.local
writes the text "CHECK_RELEASE = NO" to the configure/CONFIG_SITE.local file.
If the file does not exist, the >
sign creates the file and writes the output to it.
If the file already exists, the >
sign overwrites its contents with the new output
4.7 Build motorVMC
$ make
output
make -C ./configure install
make[1]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/configure'
perl -CSD /APSshare/epics/base-7.0.4.1/bin/rhel8-x86_64/makeMakefile.pl O.rhel8-x86_64 ../..
mkdir -p O.Common
make -C O.rhel8-x86_64 -f ../Makefile TOP=../.. \
T_A=rhel8-x86_64 install
make[2]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/configure/O.rhel8-x86_64'
Warning: RELEASE file consistency checks have been disabled
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/configure/O.rhel8-x86_64'
make[1]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/configure'
make -C ./vmcApp install
make[1]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp'
make -C ./src install
make[2]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/src'
perl -CSD /APSshare/epics/base-7.0.4.1/bin/rhel8-x86_64/makeMakefile.pl O.rhel8-x86_64 ../../..
mkdir -p O.Common
make -C O.rhel8-x86_64 -f ../Makefile TOP=../../.. \
T_A=rhel8-x86_64 install
make[3]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/src/O.rhel8-x86_64'
/usr/bin/g++ -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_X86_64_ -DUNIX -Dlinux -O3 -Wall -mtune=generic -m64 -fPIC -I. -I../O.Common -I. -I. -I.. -I../../../include/compiler/gcc -I../../../include/os/Linux -I../../../include -I/net/aquila/export/APSmaster/gateway/epics/synApps_6_2_1/support/motor-R7-2-2/include -I/APSshare/epics/synApps_6_2_1/support/asyn-R4-42/include -I/APSshare/epics/synApps_6_2_1/support/seq-2-2-9/include -I/APSshare/epics/synApps_6_2_1/support/busy-R1-7-3/include -I/APSshare/epics/synApps_6_2_1/support/ipac-2-16/include -I/APSshare/epics/synApps_6_2_1/support/lua-R3-0-2/include -I/APSshare/epics/base-7.0.4.1/include/compiler/gcc -I/APSshare/epics/base-7.0.4.1/include/os/Linux -I/APSshare/epics/base-7.0.4.1/include -MM -MF vmcDriver.d ../vmcDriver.cpp
Creating dbd file vmcSupport.dbd
perl -CSD /APSshare/epics/base-7.0.4.1/bin/rhel8-x86_64/dbdExpand.pl -I. -I.. -I../O.Common -I../../../dbd -I/net/aquila/export/APSmaster/gateway/epics/synApps_6_2_1/support/motor-R7-2-2/dbd -I/APSshare/epics/synApps_6_2_1/support/asyn-R4-42/dbd -I/APSshare/epics/synApps_6_2_1/support/seq-2-2-9/dbd -I/APSshare/epics/synApps_6_2_1/support/busy-R1-7-3/dbd -I/APSshare/epics/synApps_6_2_1/support/ipac-2-16/dbd -I/APSshare/epics/synApps_6_2_1/support/lua-R3-0-2/dbd -I/APSshare/epics/base-7.0.4.1/dbd -o vmcSupport.dbd vmc.dbd
Installing created dbd file ../../../dbd/vmcSupport.dbd
mkdir ../../../dbd
/usr/bin/g++ -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_X86_64_ -DUNIX -Dlinux -O3 -Wall -mtune=generic -m64 -fPIC -I. -I../O.Common -I. -I. -I.. -I../../../include/compiler/gcc -I../../../include/os/Linux -I../../../include -I/net/aquila/export/APSmaster/gateway/epics/synApps_6_2_1/support/motor-R7-2-2/include -I/APSshare/epics/synApps_6_2_1/support/asyn-R4-42/include -I/APSshare/epics/synApps_6_2_1/support/seq-2-2-9/include -I/APSshare/epics/synApps_6_2_1/support/busy-R1-7-3/include -I/APSshare/epics/synApps_6_2_1/support/ipac-2-16/include -I/APSshare/epics/synApps_6_2_1/support/lua-R3-0-2/include -I/APSshare/epics/base-7.0.4.1/include/compiler/gcc -I/APSshare/epics/base-7.0.4.1/include/os/Linux -I/APSshare/epics/base-7.0.4.1/include -c ../vmcDriver.cpp
../vmcDriver.cpp: In constructor ‘VirtualMotorController::VirtualMotorController(const char*, const char*, int, double, double)’:
../vmcDriver.cpp:52:21: warning: variable ‘pAxis’ set but not used [-Wunused-but-set-variable]
VirtualMotorAxis *pAxis;
^~~~~
../vmcDriver.cpp: In function ‘int VirtualMotorCreateController(const char*, const char*, int, int, int)’:
../vmcDriver.cpp:88:27: warning: variable ‘pVirtualMotorController’ set but not used [-Wunused-but-set-variable]
VirtualMotorController *pVirtualMotorController
^~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/ar -rc libvmc.a vmcDriver.o
/usr/bin/ranlib libvmc.a
/usr/bin/g++ -o libvmc.so -shared -fPIC -Wl,-hlibvmc.so -L/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/lib/rhel8-x86_64 -L/net/s100dserv/APSshare/epics/base-7.0.4.1/lib/rhel8-x86_64 -L/net/s100dserv/APSshare/epics/synApps_6_2_1/support/asyn-R4-42/lib/rhel8-x86_64 -L/net/aquila/export/APSmaster/gateway/epics/synApps_6_2_1/support/motor-R7-2-2/lib/rhel8-x86_64 -L/APSshare/epics/base-7.0.4.1/lib/rhel8-x86_64 -Wl,-rpath,/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/lib/rhel8-x86_64 -Wl,-rpath,/net/s100dserv/APSshare/epics/base-7.0.4.1/lib/rhel8-x86_64 -Wl,-rpath,/net/s100dserv/APSshare/epics/synApps_6_2_1/support/asyn-R4-42/lib/rhel8-x86_64 -Wl,-rpath,/net/aquila/export/APSmaster/gateway/epics/synApps_6_2_1/support/motor-R7-2-2/lib/rhel8-x86_64 -Wl,-rpath,/APSshare/epics/base-7.0.4.1/lib/rhel8-x86_64 -rdynamic -m64 vmcDriver.o -lmotor -lasyn -ldbRecStd -ldbCore -lca -lCom -lpthread -lreadline -lm -lrt -ldl -lgcc
Installing shared library ../../../lib/rhel8-x86_64/libvmc.so
Installing library ../../../lib/rhel8-x86_64/libvmc.a
make[3]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/src/O.rhel8-x86_64'
make[2]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/src'
make -C ./Db install
make[2]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/Db'
perl -CSD /APSshare/epics/base-7.0.4.1/bin/rhel8-x86_64/makeMakefile.pl O.rhel8-x86_64 ../../..
mkdir -p O.Common
make -C O.rhel8-x86_64 -f ../Makefile TOP=../../.. \
T_A=rhel8-x86_64 install
make[3]: Entering directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/Db/O.rhel8-x86_64'
make[3]: Nothing to be done for 'install'.
make[3]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/Db/O.rhel8-x86_64'
make[2]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp/Db'
make[1]: Leaving directory '/home/beams/USERNAME/PET-S2/epics/synApps_6_2_1/support/motorVMC/vmcApp'
4.8 Confirm build products exist
When the build is successful there should be a database definitions file (.dbd) in the top level dbd dir, as well as a static library (.a) and a dynamic library (.so) in the arch-specific lib dir.
$ ls -l dbd lib/${EPICS_HOST_ARCH}
output
dbd:
total 0
-r--r--r-- 1 username group 32 Feb 2 15:44 vmcSupport.dbd
lib/rhel8-x86_64:
total 92
-r--r--r-- 1 username group 34518 Feb 2 15:44 libvmc.a
-r-xr-xr-x 1 username group 47696 Feb 2 15:44 libvmc.so*