Managed by UT-Battelle for the Department of Energy Kay Kasemir ORNL/SNS Feb EPICS ’Stream’ Device Support
2Managed by UT-Battelle for the Department of Energy “Stream” Type Protocols Example Devices: –Temperature controllers: Lakeshore, Omega, … –Vacuum pumps: Varian, … Serial (RS-232, RS485), Networked (TCP), GPIB (IEEE-488) Text-based Command/Response What is the current temperature on channel A? “KRDG? A\n” “ E+0\n” It’s about 80 Kelvin!
3Managed by UT-Battelle for the Department of Energy Pro/Cons Seems easy –Human-readable –Testable with Hyperterm, minicom, telnet –Create Visual Basic, LabVIEW, … demo in no time But beware! –Speed and Terminators (CR, LF, CR/LF, …) can magically change Was set to something, then device power-cycled … –Must handle timeouts Don’t just hang! –Must handle errors Don’t read “MODEL 340” as 340 Kelvin
4Managed by UT-Battelle for the Department of Energy The EPICS ‘Stream’ Device Idea Protocol File “demo.proto” Terminator = CR; getTempA { out "KRDG? A"; in "%f"; } Record record(ai, "Temp:B") { field(DTYP,"stream") field(INP, getTempA TC1") field(SCAN,"5 second") } IOC st.cmd drvAsynIPPortConfigure ("TC1", " :23")
5Managed by UT-Battelle for the Department of Energy What ‘Stream Device’ does for you Connect to device –Re-connect after disconnects Allow many records to communicate via one connection –Threading, queuing, … Handle timeouts, errors –Put records into ‘alarm’ state Debug options –Log every byte sent/received
6Managed by UT-Battelle for the Department of Energy NetCat Example Using NetCat, we pretend to be a simple device. IOC with Stream Device will ask: “ B? ” We reply either –with valid reply to request for B: “ B ” –Invalid reply: “ ”, “ get lost ”, … –Not at all, which should be treated as timeout, –a shutdown of the network connection.
7Managed by UT-Battelle for the Department of Energy Full Example: Adding support to IOC configure/RELEASE: SUPPORT=/home/controls/epics/R /su pport ASYN=$(SUPPORT)/asyn STREAM=$(SUPPORT)/StreamDevice demoApp/src/Makefile demo_DBD += stream.dbd demo_DBD += asyn.dbd demo_DBD += drvAsynIPPort.dbd demo_LIBS += asyn demo_LIBS += stream
8Managed by UT-Battelle for the Department of Energy EPICS Database demoApp/Db/demo.db record(ai, "B") { field (DTYP, "stream") field (INP, getB NC") field (SCAN, "5 second") } record(ao, "current") { field (DTYP, "stream") field (OUT, setCurrent NC") field (EGU, "A") field (PREC, "2") field (DRVL, "0") field (DRVH, "60") field (LOPR, "0") field (HOPR, "60“ } record(ai, "A") { field (DTYP, "stream") field (INP, getA NC") field (SCAN, "I/O Intr") }
9Managed by UT-Battelle for the Department of Energy Protocol File iocBoot/iocdemo/demo.proto Terminator = CR LF; InTerminator = LF; ReplyTimeout = 10000; ReadTimeout = 10000; # Used with SCAN “… second”: # Prompts, then expects "B 5" getB { out "B?"; in "B %f“; } # Example with initialization, # otherwise only writes when processed setCurrent { out "CURRENT { out "CURRENT?"; in "CURRENT %f A"; } } # Used with SCAN, "I/O Intr": # Reacts to "A 5" at any time getA { PollPeriod = 50; in "A %f"; }
10Managed by UT-Battelle for the Department of Energy IOC Startup File iocBook/iocdemo/st.cmd epicsEnvSet ("STREAM_PROTOCOL_PATH", ".") drvAsynIPPortConfigure ("NC", " :6543") # ASYN_TRACE_ERROR 0x0001 # ASYN_TRACEIO_DEVICE 0x0002 # ASYN_TRACEIO_FILTER 0x0004 # ASYN_TRACEIO_DRIVER 0x0008 # ASYN_TRACE_FLOW 0x0010 # ASYN_TRACEIO_NODATA 0x0000 # ASYN_TRACEIO_ASCII 0x0001 # ASYN_TRACEIO_ESCAPE 0x0002 # ASYN_TRACEIO_HEX 0x0004 # Log some asyn info and in/out texts asynSetTraceMask("NC", 0, 4) asynSetTraceIOMask("NC", 0, 6) dbLoadRecords("db/stream.db","user=fred")
11Managed by UT-Battelle for the Department of Energy Example Session NetCat nc –l B? B 17 B? B 18 B? B 3.14 B? 34 B? IOC …write 4 B?\r\n …read 5 B 17\n … got "34" where "B " was expected … No reply from device within ms
12Managed by UT-Battelle for the Department of Energy Stream Device… Allows you to concentrate on the protocol Handles the rest –Connection –Threads –Parse results –Update record’s value and alarm state “demo.proto” Terminator = CR; getTempA { out "KRDG? A"; in "%f"; }