1 2013: The ASYN Software Module EPICS The ASYN Software Module Andy Foster Observatory Sciences Limited
Mar 30, 2015
12013: The ASYN Software Module
EPICS
The ASYN Software Module
Andy FosterObservatory Sciences Limited
22013: The ASYN Software Module
EPICSOutline
Where is the ASYN layer? What is ASYN? Key concepts of ASYN ASYN Architecture Vocabulary
Asyn Port Asyn Interfaces Asyn Command Asyn User AsynManager
Synchronous control flow Asynchronous control flow Writing ASYN device support Writing ASYN driver support Porting existing drivers to ASYN Asyn Trace asynRecord Summary Where to find more information
32013: The ASYN Software Module
EPICSWhere is the ASYN layer?
Traditionally, the interface between device and driver support
Historical name: supports “synchronous” as well as “asynchronous” devices
RECORD SUPPORT
DEVICE SUPPORT
ASYN LAYER
DATABASE ACCESS
CHANNEL ACCESS
DRIVER SUPPORT
42013: The ASYN Software Module
EPICSWhat is ASYN?
The EPICS interface between device support and driver support was only loosely defined. Device support has direct access to the
record structure and can manipulate all fields
A driver support library could have almost any API. It can even be an externally provided general purpose library
ASYN is a software module which provide facilities for interfacing device and driver support read(), write() interface with parameter
and address passing Handles some of the generic
“housekeeping” tasks in device support
52013: The ASYN Software Module
EPICSWhat is ASYN?
Asyn provides implementation of device support for standard recordsai,ao,bi,bo,mbbi,mbbo,waveform and so onHandles the details of the interaction with the record fieldsAsyn drivers only need to read/write data to/from hardware and the driver support layerNo need to write support specifically for every record
But not limited to use with EPICS device/driver supportOnly depends on libCom from EPICS baseOther ‘C’ code can talk directly to an Asyn support module (e.g. SNL, genSub)
Some support for generic communication protocolsSerial interfaces RS232/485Ethernet TCP/IP, UDP/IP
62013: The ASYN Software Module
EPICSKey concepts of ASYN
The ASYN layer has two interfaces:
Upwards to the device support layer. This has been written for all the
standard EPICS records.
Downwards to a device driver Here a set of standard interfaces have
been defined for both message passing (e.g. serial) and register reading/writing (e.g. DAC based devices).
Therefore, for a new piece of hardware, we only need to write a driver which implements one or more of the standard interfaces to the ASYN layer.
72013: The ASYN Software Module
EPICSASYN Architecture
Device support (or SNL code, another driver, or non-EPICS
software)
device device
Port (named object)
Port driver
addr=0 addr=1
Interfaces (named; Pure Virtual Functions)
asynCommon (connect, report, …)
asynOctet (write, read, setInputEos,…)
82013: The ASYN Software Module
EPICSVocabulary:ASYN Port
Provides access to a device portName (string) provides the
reference to the hardware Drivers register a port, device support
connects to it One or many devices can be
connected, addresses identify individual devices
May be blocking or non-blocking Depends on speed of device
Is configured in startup script:
drvAsynSerialPortConfigure
("COM2", "/dev/sttyS1“)
drvAsynIPPortConfigure
("fooServer", "192.168.0.10:40000“)
myDeviceDriverConfigure ("portname", parameters)
92013: The ASYN Software Module
EPICSVocabulary:ASYN Interfaces
Device support (and other ASYN clients) communicate with driver support through defined interfaces
Each interface defines a table of driver functions or methods
Examples are:
asynOctet (read, write, setInputEOS, etc) Used for message based I/O: serial, TCP/IP
asynUInt32Digital (read, write, Used for bit field registers: status word,
switches, etc
asynInt32, asynInt32Array (read, write, getBounds, …) Integer registers: ADC, DAC, encoder, … Integer arrays: spectrum analyzer,
oscilloscope
asynFloat64, asynFloat64Array (read, write,…) Floating point registers and arrays
102013: The ASYN Software Module
EPICSVocabulary:ASYN Interfaces
asynCommon (report, connect, disconnect)
report: Generates a report about the hardware device
connect/disconnect: connect/disconnect to the hardware device
Every driver must implement these!
Every port has one or many interfaces
112013: The ASYN Software Module
EPICSVocabulary:ASYN Command
An ASYN driver defines a set of commands it supports e.g.
enum FINS_COMMANDS { FINS_MODEL, …, … } (Factory Intelligent Network Service - PLC)
In an EPICS database the ASYN command is the argument at the end of the INP or OUT field. The DTYP field is set to the type of ASYN interface being used e.g.
record(waveform, "$(device):MODEL:CPU") { field(DTYP, "asynOctetRead") field(INP, "@asyn(port, addr, timeout)
FINS_MODEL") }
122013: The ASYN Software Module
EPICSVocabulary:ASYN Command
ASYN commands are supported through a special interface.
asynDrvUser ( create, getType, destroy)
create: maps the ENUM command to the string used in INP/OUT in the database getType: Looks up ENUM command based
on the database string. Destroys the resources created by
“create”.
asynStatus drvUserCreate(void *pvt, asynUser *pasynUser, const char *drvInfo, const char
**pptypeName, size_t *psize){ if (drvInfo) { if (strcmp("FINS_MODEL", drvInfo) == 0) { pasynUser->reason = FINS_MODEL; } else { } }}
132013: The ASYN Software Module
EPICSVocabulary: asynUser
Identifies the client e.g. EPICS record. Each client needs one asynUser
An “asynUser” must not be shared between parts of code that can simultaneously access a driver. For example, device support for EPICS records should create a separate “asynUser” for each record instance.
By creation of an “asynUser” we obtain a handle for accessing ports and for calling interfaces implemented by drivers. In writing ASYN device support, before doing anything you must obtain a pointer to an asynUser
pasynUser=pasynManager->createAsynUser( processCallback, timeoutCallback);
Provide 2 callbacks: processCallback is called when you are
scheduled to access the port timeoutCallback is called if port times out
142013: The ASYN Software Module
EPICSVocabulary: asynManager
Core of ASYN. Creates threads for blocking ports. Registers and finds ports and
interfaces. Schedules access to ports.
Device support and driver support do not need to implement queues or semaphores, this is handled by asynManager.
There is exactly one global instance: pasynManager
Clients ask asynManager for servicespasynManager->connectDevice(pasynUser ,
"portname", address)
pasynManager->findInterface(pasynUser, interfaceType, ...)
pasynManager->queueRequest(pasynUser, priority, timeout)
152013: The ASYN Software Module
EPICSControl flow for non-blocking port
1. Record processing calls device support.
2. Device support calls queueRequest.
3. Since the port is synchronous, queueRequest calls “lockPort” and then “processCallback”.
4. “processCallback” calls the driver. The driver returns the results of the I/O operation to “processCallback”.
5. “processCallback” returns to “queueRequest”, which calls “unlockPort” and returns to device support, which returns to record support to complete processing.
Used for devices that provide fast responses, typically VME or register based devices
162013: The ASYN Software Module
EPICSControl flow for blocking port
1. Record processing calls device support with PACT=0.
2. Device support calls queueRequest.
3. queueRequest places the request on the driver queue (the application thread can now continue).
4. The portThread removes the request from the queue.
5. The portThread calls the users “processCallback” located in device support.
6. “processCallback” calls the driver. The driver blocks until the operation is complete and returns the results of the I/O operation to “processCallback”.
7. “processCallback” calls the EPICS routine “callbackRequestProcessCallback” to make the record process again.
8. Record support calls device support again, with PACT=1. Device support updates fields in the record and returns to record support to complete the processing.
Used for ‘slow’ devices like serial or ethernet
172013: The ASYN Software Module
EPICSWriting ASYN Device Support
Step 1: Connect to the port
Before doing anything you must obtain a pointer to an asynUser pasynUser=pasynManager->createAsynUser( processCallback, timeoutCallback);
Connect to the device (port, address)status=pasynManager->connectDevice(pasynUser,
port, addr);
Find the interface (e.g. asynOctet)pasynInterface=pasynManager->findInterface (pasynUser, asynOctetType, 1);
We can now find the address of the asynOctet interface and of the private driver structure:
pasynOctet =(asynOctet *)pasynInterface->pinterface;drvPvt = pasynInterface->pdrvPvt;
The following call is made from processCallback when we have access to the port (next slide):
pasynOctet->read ( drvPvt, pasynUser,...
182013: The ASYN Software Module
EPICSStep 2: Request access to the port
Ask asynManager to put your request to the queuestatus=pasynManager->queueRequest(pasynUser,
priority, timeout);
Priorities: asynQueuePriority{Low|Medium|High}
queueRequest never blocks. Blocking port: AsynManager will call your processCallback when port is free. The callback runs in port thread.
Non blocking port: queueRequest calls processCallback.
If port is not free for timeout seconds, asynManager calls timeoutCallback.
In processCallback, you have exclusive access to the port.
192013: The ASYN Software Module
EPICSStep 3: processCallback
(asynOctet methods)
Flush (discard old input)status=pasynOctet->flush(drvPvt, pasynUser);
Write:Status = pasynOctet->write(
drvPvt,pasynUser,data,size,&bytesWritten);
Actual number of written bytes is returned in bytesWritten.
Read:status=pasynOctet->read(drvPvt,
pasynUser,buffer,maxsize,&bytesReceived,&eomReason);
Actual number of written bytes is returned in bytesReceived.
End of message reason is returned in eomReason.
202013: The ASYN Software Module
EPICSStep 3: processCallback
(asynInt32 methods)
Get boundsstatus=pasynInt32->getBounds(
drvPvt, pasynUser, &low, &high);
Limits for valid register values are returned in low and high.
Writestatus=pasynInt32->write(
drvPvt, pasynUser, value);
Readstatus=pasynInt32->read(
drvPvt, pasynUser, &value);
Current register value is returned in value.
212013: The ASYN Software Module
EPICSRules for using driver methods
Never use I/O methods outside processCallback.
Only talk to the port that has called you back.
You can do as many I/O as you like. You must always use the interface
method table pasyn{Octet|Int32|…} to access the driver.
You always need pasynUser as an argument.
All other clients of the same port (even with other addresses) have to wait until you are finished. So, remember, it’s not nice of you if your device blocks for a long time!
222013: The ASYN Software Module
EPICSWriting ASYN Driver Support
Since the interface to the device support layer has been written for most common EPICS records, we are more likely to need to write an ASYN driver.
Starting design of a new ASYN based driver Decide whether your device is
synchronous or asynchronous (timing) Choose a number of commands which
your driver will implement Identify which standard interfaces are
appropriate for communicating with the device
A driver must maintain a data structure for all its internal storage Common practice for most drivers – not
just asyn A pointer to this structure will be passed
around as an argument to the various callbacks to the driver code
232013: The ASYN Software Module
EPICSWriting ASYN Driver Support
asynCommon and asynDrvUser must be registered with asynManager
For each “data” interface, you must supply a number of methods read, write are the main ones
Each “data” interface must be initialised
242013: The ASYN Software Module
EPICSExample ASYN driver: foo
#include <asynDriver.h>#include <asynDrvUser.h>#include <asynInt32.h>
... Define functions here...
static struct asynCommon foo_Common = { fooReport, fooConnect, fooDisconnect };
static asynDrvUser foo_DrvUser = { fooCreate, fooGetType, fooDestroy};
static asynInt32 foo_Int32 = { fooInt32Read, fooInt32Write, NULL, NULL, NULL};
typedef struct drvPvt { ... char *portName; asynInterface common; asynInterface drvUser; asynInterface int32;} drvPvt;
/* Add asynInterface lines to a non-asyn driver */
252013: The ASYN Software Module
EPICSASYN driver initialisation
routinefooInit( char *portName, char *address ) /* startup script */{ drvPvt *pFoo; pFoo = callocMustSucceed(1, sizeof(drvPvt), FUNCNAME); pdrvPvt->portName = epicsStrDup(portName); pFoo->common.interfaceType = asynCommonType; pFoo->common.pinterface = (void *)&foo_Common; pFoo->common.drvPvt = pFoo;
pFoo->drvUser.interfaceType = asynDrvUserType; pFoo->drvUser.pinterface = (void *)&foo_DrvUser; pFoo->drvUser.drvPvt = pFoo;
pFoo->int32.interfaceType = asynInt32Type; pFoo->int32.pinterface = (void *)&foo_Int32; pFoo->int32.drvPvt = pFoo;
pasynManager->registerPort( pFoo->portName, ASYN_MULTIDEVICE | ASYN_CANBLOCK, /* ASYN_MULTIDEVICE set: port supports > 1 device */ /* ASYN_CANBLOCK set: separate thread for the port */ 1, /* autoconnect: asynmanager connects automatically */ 0, /* medium priority for thread */ 0 ) /* default stack size for thread */
pasynManager->registerInterface (pFoo->portName, &pFoo->common); pasynManager->registerInterface (pFoo->portName, &pFoo->drvUser); pasynInt32Base->initialize (pFoo->portName, &pFoo->int32);}
262013: The ASYN Software Module
EPICSImplementation of driver “read”
functionstatic asynStatus fooInt32Read( void *drvPvt, asynUser *pasynUser, epicsInt32 *value){ drvPvt *pdrvPvt = (drvPvt *)drvPvt; epicsInt32 addr; /* Find out which address on the device we are reading */ pasynManager->getAddr(pasynUser,&addr);
/* pasynUser->reason is set in the asynDrvUser create method – see earlier */
switch ( pasynUser->reason ) { case AMP_GAIN: *value = readAmpGainFromDevice(); break;
case AMP_CLOCK_READ: *value = readAmpClock(); break; } return asynSuccess;}
272013: The ASYN Software Module
EPICSPorting existing drivers to ASYN
Depends on the existing design Does it have both device and driver support?
Device support is supplied by asyn so remove or untangle existing device support
Identify and name specific commands to communicate with the device Implement an enum type with the commands
and a lookup table for string representations
Implement driver read + write functions Typically with big switch/case structure to
handle different ‘reasons’ or ‘commands’
Implement driver structure A driver structure should already exist
(common in way of keeping track of a device) Add the asyn interface pointers to the
structure Initialisation routine must register and
initialize the relevant interfaces
282013: The ASYN Software Module
EPICSVocabulary: asynTrace
Diagnostic facility
Provides routines to call for diagnostic messages: asynPrint(), asynPrintIO()
Several masks or levels can be selected for debugging purposes
Provides consistent debugging mechanism for drivers
292013: The ASYN Software Module
EPICSasynRecord
Special record type that can use all asyn interfaces.
Can connect to different ports at run-time. Is a good debug tool. Access to options, including tracing. Comes with set of medm screens for
different interfaces. Can handle simple devices:
e.g. asynOctet: write one string, read one string
If a new instrument arrives that has a serial, GPIB or ethernet port, then it is often possible to communicate with it just by attaching an asynRecord i.e. a database containing one record!
312013: The ASYN Software Module
EPICSSummary Advantages of
ASYN Drivers implement standard interfaces that
can be accessed from: Multiple record types SNL programs Other drivers
Generic device support eliminates the need for separate device support in 90% of cases
Consistent trace/debugging at (port, addr) level
asynRecord can be used for testing, debugging, and actual I/O applications
Easy to add ASYN interfaces to existing drivers: Register port, implement interface write(),
read() and change debugging output Preserve 90% of driver code
322013: The ASYN Software Module
EPICSMore information
AsynDriver www.aps.anl.gov/epics/modules/soft/asyn/
StreamDevice epics.web.psi.ch/software/streamdevice/
linuxGpib linux-gpib.sourceforge.net/
Drivers/device supports using asynDriver www.aps.anl.gov/aod/bcda/synApps/
Talks about asynDriver www.aps.anl.gov/aod/bcda/
epicsgettingstarted/iocs/ASYN.html www.aps.anl.gov/epics/docs/USPAS2007.php