32
1 2013: The ASYN Software Module EPICS The ASYN Software Module Andy Foster Observatory Sciences Limited

1 2013: The ASYN Software Module EPICS The ASYN Software Module Andy Foster Observatory Sciences Limited

Embed Size (px)

Citation preview

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!

302013: The ASYN Software Module

EPICSasynRecord medm screens

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