1 / 32

The ASYN Software Module

The ASYN Software Module. Andy Foster Observatory Sciences Limited. Outline. 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

holly
Download Presentation

The ASYN Software Module

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The ASYN Software Module Andy Foster Observatory Sciences Limited

  2. Outline • 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

  3. Where is the ASYN layer? • Traditionally, the interface between device and driver support • Historical name: supports “synchronous” as well as “asynchronous” devices CHANNEL ACCESS DATABASE ACCESS RECORD SUPPORT DEVICE SUPPORT ASYN LAYER DRIVER SUPPORT

  4. What 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

  5. What is ASYN? • Asyn provides implementation of device support for standard records • ai,ao,bi,bo,mbbi,mbbo,waveform and so on • Handles the details of the interaction with the record fields • Asyn drivers only need to read/write data to/from hardware and the driver support layer • No need to write support specifically for every record • But not limited to use with EPICS device/driver support • Only depends on libCom from EPICS base • Other ‘C’ code can talk directly to an Asyn support module (e.g. SNL, genSub) • Some support for generic communication protocols • Serial interfaces RS232/485 • Ethernet TCP/IP, UDP/IP

  6. Key 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.

  7. ASYN Architecture Device support (or SNL code, another driver, or non-EPICS software) Interfaces (named; Pure Virtual Functions) asynCommon (connect, report, …) asynOctet (write, read, setInputEos,…) Port (named object) Port driver addr=0 addr=1 device device

  8. Vocabulary: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)

  9. Vocabulary: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

  10. Vocabulary: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

  11. Vocabulary:ASYN Command • An ASYN driver defines a set of commands it supportse.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") }

  12. Vocabulary: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”. asynStatusdrvUserCreate(void *pvt, asynUser*pasynUser, constchar *drvInfo, constchar **pptypeName, size_t *psize) { if (drvInfo) { if (strcmp("FINS_MODEL", drvInfo) == 0) { pasynUser->reason = FINS_MODEL; } else { } } }

  13. Vocabulary: 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

  14. Vocabulary: 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 services pasynManager->connectDevice(pasynUser , "portname", address) pasynManager->findInterface(pasynUser, interfaceType, ...) pasynManager->queueRequest(pasynUser, priority, timeout)

  15. Control flow for non-blocking port • Record processing calls device support. • Device support calls queueRequest. • Since the port is synchronous, queueRequest calls “lockPort” and then “processCallback”. • “processCallback” calls the driver. The driver returns the results of the I/O operation to “processCallback”. • “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

  16. Control flow for blocking port • Record processing calls device support with PACT=0. • Device support calls queueRequest. • queueRequest places the request on the driver queue (the application thread can now continue). • The portThread removes the request from the queue. • The portThread calls the users “processCallback” located in device support. • “processCallback” calls the driver. The driver blocks until the operation is complete and returns the results of the I/O operation to “processCallback”. • “processCallback” calls the EPICS routine “callbackRequestProcessCallback” to make the record process again. • 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

  17. Writing ASYN Device SupportStep 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,...

  18. Step 2: Request access to the port • Ask asynManager to put your request to the queue status=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.

  19. Step 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.

  20. Step 3: processCallback (asynInt32 methods) • Get bounds status=pasynInt32->getBounds( drvPvt, pasynUser, &low, &high); • Limits for valid register values are returned in low and high. • Write status=pasynInt32->write( drvPvt, pasynUser, value); • Read status=pasynInt32->read( drvPvt, pasynUser, &value); • Current register value is returned in value.

  21. Rules 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!

  22. Writing 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

  23. Writing 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

  24. Example 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 */

  25. ASYN driver initialisation routine fooInit( 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); }

  26. Implementation of driver “read” function static 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; }

  27. Porting 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

  28. Vocabulary: 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

  29. asynRecord • 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!

  30. asynRecord medm screens

  31. Summary 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

  32. More 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

More Related