...
- support already present in <ibek-support>
- support present as git project
- support not present at all → put in the condition 2
Use an existing ibek support
Anchor | ||||
---|---|---|---|---|
|
If a support is present in <ibek-support>, it's very simple to use it just create a yaml that instantiates your device(s).
...
Code Block | ||||
---|---|---|---|---|
| ||||
docker run -p 5064:5064/udp -p 5064:5064/tcp -p 5065:5065/udp -p 5065:5065/tcp -it -v .:/epics/ioc/config baltig.infn.it:4567/epics-containers/infn-epics-ioc:localdevel |
A generic asyn motor OPI interface can be used to drive the motor. Motor OPIs Remember to add localhost to your phoebus
...
Once the IOC runs correctly as docker can be inserted in the EPIK8S configuration
Build a support from existing git support
This is path is more complex, but gives much more satisfaction, in fact each time you add a new support as much generic possible you greatly simplify the life of your self and in principle many other people will use the your support.
Step 1 create a directory inside ibek-support
Create by copy and renaming one of the existing support. Suppose you want to add the support for <mydevmodule>, you should have:
...
So in general just two file must be added: install.sh and mydevmodule.ibek.support.yaml.
install.sh
This file contains instructions on howto retrieve, compile and link dependencies of your module mydevmodule. In general if the mydevmodule is well structured from a build epics point of view needs only to be patched like that:
Code Block | ||||
---|---|---|---|---|
| ||||
#!/bin/bash # ARGUMENTS: # $1 VERSION to install (must match repo tag) VERSION=${1} NAME=<mydevmodule> ## as compare in the git repository FOLDER=$(dirname $(readlink -f $0)) # log output and abort on failure set -xe # get the source and fix up the configure/RELEASE files ibek support git-clone ${NAME} ${VERSION} --org http://gitrepo ## repository git root ibek support register ${NAME} # declare the libs and DBDs that are required in ioc/iocApp/src/Makefile ibek support add-libs <mydevmodulelib> <support1lib> <support2lib> asyn ## optional libraries that must be linked ibek support add-dbds <mydevmodule>.dbd <optsupport1.dbd> <optsupport2>.dbd ### optional dbd supports # global config settings ${FOLDER}/../_global/install.sh ${NAME} # compile the support module ibek support compile ${NAME} # prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. ibek support generate-links ${FOLDER} |
mydevmodule.ibek.support.yaml
This also has a very simple syntax and gives instructions on how to expand a future yaml configuration.
...
Code Block | ||||
---|---|---|---|---|
| ||||
# yaml-language-server: $schema=https://github.com/epics-containers/ibek/releases/download/1.5.0/ibek.support.schema.json # #errlogInit(5000) # < envPaths # # Tell EPICS all about the record types, device-support modules, drivers, # # etc. # dbLoadDatabase("../../dbd/newport.dbd") # newport_registerRecordDeviceDriver(pdbbase) # ### Motors # dbLoadTemplate "motor.substitutions.SMC100" # ### Serial port setup # drvAsynSerialPortConfigure("serial1", "/dev/ttyS0", 0, 0, 0) # asynSetOption(serial1,0,baud,57600) # asynOctetSetInputEos("serial1",0,"\r\n") # asynOctetSetOutputEos("serial1",0,"\r\n") # ### Newport SMC100 support # # (driver port, serial port, axis num, ms mov poll, ms idle poll, egu per step) # SMC100CreateController("SMC100_1", "serial1",1, 100, 0, "0.00005") # file "$(TOP)/db/basic_asyn_motor.db" # { # pattern # {P, N, M, DTYP, PORT, ADDR, DESC, EGU, DIR, VELO, VBAS, ACCL, BDST, BVEL, BACC, MRES, PREC, DHLM, DLLM, INIT, RTRY} # {IOC:, 1, "m$(N)", "asynMotor", "SMC100_1", 0, "GTS30V", mm, Pos, 1, 0, .2, 0, .5, .2, 0.00001, 6, 25, -5, ""} # } # iocInit module: motorNewport defs: - name: SMC100CreateController description: |- Creates a SMC100 motion controller connected to an ethernetToSerialServer args: - type: id name: controllerName description: |- The name of the controller and its Asyn Port Name - type: str name: P description: |- Device PV Prefix - type: str name: IP description: |- IP address of the ethernet2serial default: 127.0.0.1 ## localhost - type: int name: TCPPORT description: |- Port of the ethernet2serial default: 4001 - type: int name: POLL description: |- Movement poll ms default: 100 - type: float name: EGUXSTEP description: |- EGU PER STEP default: 0.00005 - type: int name: ASYNPRIO description: |- ASYN PRIORITY, Default : 0 default: 0 - type: int name: AUTOCONNECT description: |- Asyn auto connect 0: Auto connection 1: no Auto connection default: 0 - type: int name: NOPRECESSESOS description: |- ASYN noProcessEos, Default : 0 https://epics.anl.gov/tech-talk/2020/msg01705.php default: 0 - type: int name: numAxes description: |- The number of axes to create pre_init: - value: | # epicsEnvSet "STREAM_PROTOCOL_PATH", "$(MOTORNEWPORT)/protocol/" # Create Asyn Port drvAsynIPPortConfigure("{{controllerName}}_ASYN", "{{IP}}:{{TCPPORT}}", {{ASYNPRIO}}, {{AUTOCONNECT}}, {{NOPRECESSESOS}}) # asynInterposeEosConfig("{{controllerName}}_ASYN",0,2000,0) SMC100CreateController("SMC100_{{controllerName}}", "{{controllerName}}_ASYN","{{numAxes}}", "{{POLL}}", 0, "{{EGUXSTEP}}") asynOctetSetInputEos({{controllerName}}_ASYN,0,"\r\n") asynOctetSetOutputEos({{controllerName}}_ASYN,0,"\r\n") asynReport 10 - name: motorAxis description: |- Creates a motor axis args: - type: object name: controller description: |- a reference to the motion controller - type: str name: M description: |- PV suffix for the motor record - type: int name: ADDR description: |- The axis number (allowed to be from 0 to controller.numAxes-1) - type: str name: DESC description: |- The description of the axis - type: int name: DLLM description: |- The low limit of the axis default: -5 - type: int name: DHLM description: |- The high limit of the axis default: 25 - type: int name: VELO description: |- Velocity default: 1 - type: int name: home description: |- The home position of the axis (in counts) - type: int name: start description: |- The starting position of the axis (in counts) default: 0 - type: enum name: DIR description: |- The direction of the axis default: 0 values: Pos: 0 Neg: 1 - type: str name: EGU description: |- Engineering Units default: "mm" - type: float name: VBAS description: |- Base Velocity (EGU/s) default: 0.2 - type: float name: ACCL description: |- Seconds to Velocity default: 0.2 - type: int name: BDST description: |- BL Distance (EGU) default: 0 - type: float name: BVEL description: |- BL Velocity (EGU/s) default: 0.5 - type: float name: BACC description: |- BL Seconds to Veloc. default: 0.2 - type: float name: MRES description: |- Motor Step Size (EGU) default: 0.00001 - type: int name: PREC description: |- Display precision (EGU) default: 6 databases: # TODO as this is a simulation I have hard coded some of the DB fields, # but these could easily be made into arguments above # # Note: supplying no value means that the argument of the same name is used # (the most common case - if you contrive to make args and db fields the same. # Which is good idea for ease of transition from traditional IOCs) - file: basic_asyn_motor.db args: P: "{{controller.P}}" N: "{{ADDR +1 }}" M: DTYP: "asynMotor" PORT: "SMC100_{{controller}}" ADDR: DESC: EGU: DIR: VELO: VBAS: ACCL: BDST: BVEL: BACC: MRES: PREC: DHLM: DLLM: INIT: "" post_init: - value: | dbl |
Step 2 add an entry into Dockerfile
Modify the Dockerfile in the project:
Code Block | ||
---|---|---|
| ||
##### build stage ############################################################## ARG TARGET_ARCHITECTURE ARG BASE=7.0.8ec1b3 ARG REGISTRY=ghcr.io/epics-containers FROM ${REGISTRY}/epics-base-${TARGET_ARCHITECTURE}-developer:${BASE} AS developer # The devcontainer mounts the project root to /epics/generic-source # Using the same location here makes devcontainer/runtime differences transparent. ENV SOURCE_FOLDER=/epics/generic-source # connect ioc source folder to its know location RUN ln -s ${SOURCE_FOLDER}/ioc ${IOC} # Get latest ibek while in development. Will come from epics-base when stable COPY requirements.txt requirements.txt RUN pip install --upgrade -r requirements.txt WORKDIR ${SOURCE_FOLDER}/ibek-support # copy the global ibek files COPY ibek-support/_global/ _global COPY ibek-support/iocStats/ iocStats RUN iocStats/install.sh 3.2.0 ################################################################################ # TODO - Add further support module installations here ################################################################################ COPY ibek-support/asyn/ asyn/ RUN asyn/install.sh R4-44 COPY ibek-support/autosave/ autosave/ RUN autosave/install.sh R5-11 COPY ibek-support/busy/ busy/ RUN busy/install.sh R1-7-3 COPY ibek-support/StreamDevice/ StreamDevice/ RUN StreamDevice/install.sh 2.8.24 COPY ibek-support/sscan/ sscan/ RUN sscan/install.sh R2-11-6 COPY ibek-support/calc/ calc/ RUN calc/install.sh R3-7-5 COPY ibek-support/motor/ motor/ RUN motor/install.sh R7-3 COPY ibek-support/motorMotorSim/ motorMotorSim/ RUN motorMotorSim/install.sh R1-2 COPY ibek-support/ADCore/ ADCore/ RUN ADCore/install.sh R3-13 COPY ibek-support/ADGenICam ADGenICam/ RUN ADGenICam/install.sh R1-9 COPY ibek-support/ADSimDetector ADSimDetector/ RUN ADSimDetector/install.sh R2-10 COPY ibek-support/modbus/ modbus/ RUN modbus/install.sh R3-3 COPY ibek-support/screen-epics-ioc screen-epics-ioc/ RUN screen-epics-ioc/install.sh v1.3.1 COPY ibek-support/motorNewport motorNewport/ RUN motorNewport/install.sh R1-2-1 # COPY ibek-support/easy-driver-epics/ easy-driver-epics/ # RUN easy-driver-epics/install.sh master COPY ibek-support/mydevmodule mydevmodule ### HERE RUN mydevmodule/install.sh master ## HERE # get the ioc source and build it COPY ioc/ ${SOURCE_FOLDER}/ioc RUN cd ${IOC} && ./install.sh && make ##### runtime preparation stage ################################################ FROM developer AS runtime_prep # get the products from the build stage and reduce to runtime assets only RUN ibek ioc extract-runtime-assets /assets ${SOURCE_FOLDER}/ibek* ##### runtime stage ############################################################ FROM ${REGISTRY}/epics-base-${TARGET_ARCHITECTURE}-runtime:${BASE} AS runtime # get runtime assets from the preparation stage COPY --from=runtime_prep /assets / # install runtime system dependencies, collected from install.sh scripts RUN ibek support apt-install-runtime-packages --skip-non-native ENV TARGET_ARCHITECTURE ${TARGET_ARCHITECTURE} CMD ["/bin/bash", "-c", "${IOC}/start.sh"] |
Step 3 build docker image
building:
Code Block | ||
---|---|---|
| ||
git clone https://baltig.infn.it/epics-containers/infn-epics-ioc.git --recurse-submodules
cd infn-epics-ioc
docker build --build-arg TARGET_ARCHITECTURE="linux" --build-arg TARGETARCH="amd64" -t baltig.infn.it:4567/epics-containers/infn-epics-ioc:local . |
building development:
Code Block | ||
---|---|---|
| ||
git clone https://baltig.infn.it/epics-containers/infn-epics-ioc.git --recurse-submodules
cd infn-epics-ioc
docker build -f Dockerfile.devel --build-arg TARGET_ARCHITECTURE="linux" --build-arg TARGETARCH="amd64" -t baltig.infn.it:4567/epics-containers/infn-epics-ioc:devel . |
Step 4 motor yaml instance
Write a mymotor.yaml ibek instance of the support just created and built:
Code Block | ||||
---|---|---|---|---|
| ||||
gioc_name: rfmotors
description: RF motors
entities:
- type: motorNewport.SMC100CreateController
controllerName: NEWPORT001
P: "SPARC:RF:"
IP: 192.168.190.56
TCPPORT: 4001
numAxes: 1
- type: motorNewport.motorAxis
controller: NEWPORT001
M: "m0"
DESC: "Axis"
ADDR: 0
DLLM: -25
DHLM: 25
home: 1
start: 10
VELO: 1 |
test instance
the following lines will mount the current directory that contains mymotor.yaml in the container /epics/ioc/config and will expose CA ports, then run the support just created:
Code Block | ||||
---|---|---|---|---|
| ||||
docker run -p 5064:5064/udp -p 5064:5064/tcp -p 5065:5065/udp -p 5065:5065/tcp -p 5075:5075/tcp -p 5076:5076/udp -it -v .:/epics/ioc/config -v .:/epics/ioc/config baltig.infn.it:4567/epics-containers/infn-epics-ioc:local
root@3870c1890419:/epics/generic-source/ioc/config# /epics/ioc/start.sh
... io log
....
....
|
the following lines use the development image:
Code Block | ||||
---|---|---|---|---|
| ||||
cd <myibek yaml instance>
docker run -p 5064:5064/udp -p 5064:5064/tcp -p 5065:5065/udp -p 5065:5065/tcp -p 5075:5075/tcp -p 5076:5076/udp -it -v .:/epics/ioc/config baltig.infn.it:4567/epics-containers/infn-epics-ioc:devel
root@3870c1890419:/epics/generic-source/ioc/config# /epics/ioc/start.sh
...
log
...
|
For test refer to existing ibek support