Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

4.1 Reuse a device startup fragment

Move the Chapter 3 device setup into a reusable IOC shell (iocsh) file. Its macros let one file configure several devices.

Complete Test IOC communication with the simulator first, and stop the Chapter 3 IOC and simulator. Open three Bash terminals on the same host with these roles and settings:

TerminalRoleWorking directoryEnvironment
Terminal 1TCP echo simulator (9399)jeonglee_Demo/simulator/No EPICS environment required
Terminal 2Build and IOC (make, ./st2.cmd)jeonglee_Demo/ then jeonglee_Demo/iocBoot/iocB46_182-jeonglee_Demo/source "$TREE/setEpicsEnv.bash"
Terminal 3CA and PVA clientAny directorysource "$TREE/setEpicsEnv.bash", export EPICS_CA_AUTO_ADDR_LIST=NO EPICS_CA_ADDR_LIST=127.0.0.1, export EPICS_PVA_AUTO_ADDR_LIST=NO EPICS_PVA_ADDR_LIST=127.0.0.1

In each EPICS terminal, set TREE to your installation path from lesson 1.1 (such as "$HOME/epics/1.5.0/debian-13/7.0.10") before running source "$TREE/setEpicsEnv.bash".

  1. In terminal 1, start one echo server from jeonglee_Demo/simulator/:

    ./tcpserver.bash 9399
    

    Leave it running for this lesson. Do not start another on the same port.

  2. In terminal 2 inside jeonglee_Demo/jeonglee_DemoApp/iocsh/, save the following file as training_device.iocsh:

    # PREFIX, DEVICE, DATABASE_TOP, and PORT_NAME are required.
    # HOST defaults to loopback; PORT defaults to 9399.
    # Set ASYNTRACE empty to enable the trace command.
    drvAsynIPPortConfigure("$(PORT_NAME)", "$(HOST=127.0.0.1):$(PORT=9399)", 0, 0, 0)
    asynOctetSetInputEos("$(PORT_NAME)", 0, "\n")
    asynOctetSetOutputEos("$(PORT_NAME)", 0, "\n")
    $(ASYNTRACE=#--)asynSetTraceMask($(PORT_NAME), -1, ERROR|FLOW|DRIVER)
    dbLoadRecords("$(DATABASE_TOP)/training.db", "P=$(PREFIX),R=$(DEVICE),PORT=$(PORT_NAME)")
    

    $(NAME=default) supplies a default macro value. ASYNTRACE defaults to a comment prefix; an empty value enables that command. The asyn port and database use the same PORT_NAME.

  3. In terminal 2 from the jeonglee_Demo/ application root, install the fragment:

    make
    ls iocsh/training_device.iocsh
    

    Edit the source under jeonglee_DemoApp/iocsh/, then run make to update the installed copy under iocsh/.

  4. In terminal 2 inside iocBoot/iocB46_182-jeonglee_Demo/, save this as st2.cmd:

    #!../../bin/linux-x86_64/jeonglee_Demo
    on error break
    < envPaths
    epicsEnvSet("DB_TOP", "$(TOP)/db")
    epicsEnvSet("DATABASE_TOP", "$(DB_TOP)")
    epicsEnvSet("STREAM_PROTOCOL_PATH", "$(DB_TOP)")
    epicsEnvSet("PREFIX", "jeonglee:")
    epicsEnvSet("DEVICE", "myoffice:")
    epicsEnvSet("IOCNAME", "B46_182-jeonglee_Demo")
    epicsEnvSet("IOC", "iocB46_182-jeonglee_Demo")
    dbLoadDatabase("$(TOP)/dbd/jeonglee_Demo.dbd")
    jeonglee_Demo_registerRecordDeviceDriver(pdbbase)
    
    # Select exactly one call below.
    iocshLoad("$(TOP)/iocsh/training_device.iocsh", "PORT_NAME=LocalTCPServer")
    #--iocshLoad("$(TOP)/iocsh/training_device.iocsh", "PORT_NAME=LocalTCPServer,HOST=127.0.0.1,PORT=9399")
    #--iocshLoad("$(TOP)/iocsh/training_device.iocsh", "PORT_NAME=LocalTCPServer,PORT=9399,ASYNTRACE=")
    
    iocInit()
    dbl
    

    The environment supplies PREFIX, DEVICE, and DATABASE_TOP. The active iocshLoad call supplies the port name. This IOC already registered its compiled support; the fragment configures one device.

  5. In terminal 2 from iocBoot/iocB46_182-jeonglee_Demo/, start the IOC:

    chmod +x st2.cmd
    ./st2.cmd
    

    In terminal 3, direct CA and PVA searches to loopback, send a command, and read the reply:

    export EPICS_CA_AUTO_ADDR_LIST=NO EPICS_CA_ADDR_LIST=127.0.0.1
    export EPICS_PVA_AUTO_ADDR_LIST=NO EPICS_PVA_ADDR_LIST=127.0.0.1
    caput -c jeonglee:myoffice:Cmd STATUS?
    caget -t jeonglee:myoffice:Cmd-RB
    

    The reply is STATUS?. The IOC lists the same two records as Chapter 3.

Exercise: Change fragment arguments

Stop the IOC in terminal 2 with exit. Test each commented iocshLoad call by removing its #-- and commenting out the active call. Restart the IOC for each variant. Exactly one call must be active.

The second call passes the host and port explicitly. The third enables asyn trace output. Both retain the same PV names and echo behavior.

Comment out all three calls and restart. dbl lists no records because no device database was loaded. Restore one call before the next lesson.

Finish by entering exit in terminal 2 and stopping the simulator in terminal 1 with Ctrl+C.

iocshLoad runs configuration inside an IOC. It does not load installed module libraries. Chapter 6 teaches the separate iocsh.bash module loader.