一、介绍
这部分描述基于寄存器设备的接口。为以下提供了支持:
- Int32:以32位整数出现的寄存器。
- Int64:以64位整数出现的寄存器。
- UInt32Digital:以32位无符号整数出现的寄存器,并且掩码可用于寻址特定的位。
- Float64:以双精度浮点出现的寄存器。
- Int8Array:8位整数的数组。
- Int16Array:16位整数的数组。
- Int32Array:32位整数的数组。
- Int64Array:64位整数的数组。
- Float32Array:单精度浮点的数组。
- Float64Array:双精度浮点的数组。
- Enum:字符串,整数值和整数严重性的数组。
- GenericPointer:void * 指针。
注意:硬件可以注册更小的尺寸,例如16位寄存器。标准接口仍然可以设置未用位为0。
对于所有这些接口,提供了一个默认实现和一个同步实现。我们使用Int32作为一个示例。
1) asynInt32:一个带有以下方法的接口:read, write, getBounds, registerIngterrupt和cancelInterruptUser。
2) asynInt32Base:一个由实现了asynInt32的驱动程序实现的接口。它也有一个那些的实现:
- 注册这个asynInt32接口
- 有用于read, write和getBounds的默认方法。在被传递给初始化的接口中一个空方法被一个asynInt32Base实现的方法替代。
- 实现了registerInterruptUser和cancelInterruptUser。调用者应该把这些方法留空,因为asynIntBase总是用它的实现替代这些方法。
实现了asynInt32的驱动程序通常调用asynInt32Base:initialize。它实现了registerInterruptUser和cancelInterruptUser。如果驱动程序提供中断支持,它必须:
- 调用pasynInt32Base->initialize
- 调用pasynManager->registerInterruptSource
- 与asynManager交互,调用已经注册了asynInt32Base:registerInterruptUser的用户。驱动程序在有新数据可用时调用用户。
asyn/testEpicsApp/src/int32Driver.c提供了一个如何为中断提供支持的示例。
3) asynInt32SyncIO:一个asynInt32的同步接口。
二、addr--它对基于寄存器的接口意味着什么?
底层基于寄存器的驱动程序通常是多设备的。addr的含义是:
- Int32:驱动程序支持一个Int32值的数组。addr选择一个数组元素。例如,一个16通道ADC支持addr从0到15。
- Int64:驱动程序支持一个Int64值的数组。addr选择一个数组元素。
- Int8Array:每个addr是一个Int8值的数组。
- Int16Array:每个addr是一个Int16值的数组。
- Int32Array:每个addr是一个Int32值的数组。
- Int64Array:每个addr是一个Int64值的数组。
- Float64:驱动程序支持一个Float64值的数组。addr选择一个数组元素。
- Float32Array:每个addr是一个Float32值的数组。
- Float64Array:每个addr是一个Float64值的数组。
- UInt32Digital:驱动程序支持一个UInt32值的数组。addr选择一个数组元素。例如,一个128位数字I/O模块以一个4个UInt32寄存器出现。
三、示例驱动程序
两个实现并且使用这个接口的驱动程序示例是:
- 模拟到数字转换器:一个示例是一个16通道ADC。驱动程序实现了接口asynCommon和asynInt32。它使用接口asynInt32Base。它可以调用asynManager:interruptStart和asynManager:interruptEnd来支持中断。它可以使用pasynUser->reason和addr来确定要调用哪个回调。asyn/testEpicsApp/int32Driver.c是一个如何实现一个实现了asynInt32和asynFloat64的驱动程序的软示例。
- 数字I/O模块:一个示例是一个64位数字输入和数字输出模块。这个驱动程序实现了接口asynCommon和asynUInt32Digital。它使用了接口asynUInt32DigitalBase。它可以调用asynManager:interruptStart和asynManager:interruptEnd来支持中断。它可以使用reason,mask和addr来决定要调用哪些回调。asyn/testEpicsApp/uintDigitalDriver.c是一个实现了asynUInt32Digital的驱动程序的软示例。
四、asynInt32XX(XX=32或64)
asynIntXX描述了由使用整数用于与设备进行通信的驱动程序实现的方法。
typedef void (*interruptCallbackInt32)(void *userPvt, asynUser *pasynUser,
epicsInt32 data);
typedef struct asynInt32Interrupt {
int addr;
asynUser *pasynUser;
interruptCallbackInt32 callback;
void *userPvt;
} asynInt32Interrupt;
#define asynInt32Type "asynInt32"
typedef struct asynInt32 {
asynStatus (*write)(void *drvPvt, asynUser *pasynUser, epicsInt32 value);
asynStatus (*read)(void *drvPvt, asynUser *pasynUser, epicsInt32 *value);
asynStatus (*getBounds)(void *drvPvt, asynUser *pasynUser,
epicsInt32 *low, epicsInt32 *high);
asynStatus (*registerInterruptUser)(void *drvPvt,asynUser *pasynUser,
interruptCallbackInt32 callback, void *userPvt,
void **registrarPvt);
asynStatus (*cancelInterruptUser)(void *drvPvt, asynUser *pasynUser,
void *registrarPvt);
} asynInt32;
/*
asynInt32Base做以下事情:
为asynInt32调用registerInterface。
提供所有方法的默认实现。
可以直接调用registerInterruptUser和cancelInterruptUser,而不是通过queueRequest。
*/
#define asynInt32BaseType "asynInt32Base"
typedef struct asynInt32Base {
asynStatus (*initialize)(const char *portName,
asynInterface *pint32Interface);
} asynInt32Base;
epicsShareExtern asynInt32Base *pasynInt32Base;
asynIntXX
write | 写一个整数到设备 |
read | 从设备读取一个整数 |
getBounds | 获取范围。例如,一个16位ADC可以设置low=-32768和high=32767 |
registerInterruptUser | 注册一个当新数据可用时将被调用的回调。因为可以直接调用它,而不是通过一个queueRequest,这个方法一定不能阻塞。 |
cancelInterruptUser | 取消一个回调。因为能够直接调用它,而不是通过queueRequest,这个方法一定不能阻塞。 |
asynIntXXBase是一个接口和相关联代码,实现了接口asynIntXX的驱动程序使用它。asynInt32XXXBase提供了处理registerInterruptUser/cancelInterruptUser的代码。驱动程序必须自己通过对asynManager:interruptStart和asynManager:interruptEnd的调用调用回调。
asynIntXXBase
initialize | 在一个驱动程序调用registerPort后,它可以调用 pasynIntXXBase->initialize(... 在这个asynInterface中任何空方法被默认实现替代。 |
每个方法的默认实现做实现事情:
asynIntXX
write | 报告一个错误"write it not supported"并且返回asynError |
read | 报告一个错误"read it not supported"并且返回asynError |
getBounds | 报告一个错误"getBounds it not supported"并且返回asynError |
registerInterruptUser | 注册一个中断回调 |
cancelInterruptUser | 取消这个回调 |
五、asynIntXXSyncIO(XX=32或64)
asynIntXXSyncIO描述一个asynInt32XX的同步接口。调用它的代码必须愿意阻塞。
#define asynInt32SyncIOType "asynInt32SyncIO"
typedef struct asynInt32SyncIO {
asynStatus (*connect)(const char *port, int addr,
asynUser **ppasynUser, const char *drvInfo);
asynStatus (*disconnect)(asynUser *pasynUser);
asynStatus (*write)(asynUser *pasynUser, epicsInt32 value,double timeout);
asynStatus (*read)(asynUser *pasynUser, epicsInt32 *pvalue,double timeout);
asynStatus (*getBounds)(asynUser *pasynUser,
epicsInt32 *plow, epicsInt32 *phigh);
asynStatus (*writeOnce)(const char *port, int addr,
epicsInt32 value,double timeout, const char *drvInfo);
asynStatus (*readOnce)(const char *port, int addr,
epicsInt32 *pvalue,double timeout, const char *drvInfo);
asynStatus (*getBoundsOnce)(const char *port, int addr,
epicsInt32 *plow, epicsInt32 *phigh,const char *drvInfo);
} asynInt32SyncIO;
epicsShareExtern asynInt32SyncIO *pasynInt32SyncIO;
asynIntXXSyncIO
connect | 连接一个端口和地址,返回一个指向asynUser的指针。 |
disconnect | 断开。这释放由connect分配的所有资源 |
write | 调用pasynIntXX->write并且等待这个操作结束或超时 |
read | 调用pasynIntXX->read并且等待这个操作结束或超时 |
getBounds | 调用pasynIntXX->getBounds并且等待这个操作结束或者超时 |
writeOnce | 这进行一次连接,write,断开。 |
readOnce | 这进行一次连接,read,断开。 |
getBoundsOnce | 这进行一次连接,getBounds,断开。 |
六、asynUInt32Digital
asynUInt32Digital描述了通过一个Int32寄存器的比特位进行通信的方法。
typedef enum {
interruptOnZeroToOne, interruptOnOneToZero, interruptOnBoth
} interruptReason;
typedef void (*interruptCallbackUInt32Digital)(void *userPvt,
asynUser *pasynUser, epicsUInt32 data);
typedef struct asynUInt32DigitalInterrupt {
epicsUInt32 mask;
int addr;
asynUser *pasynUser;
interruptCallbackUInt32Digital callback;
void *userPvt;
} asynUInt32DigitalInterrupt;
#define asynUInt32DigitalType "asynUInt32Digital"
typedef struct asynUInt32Digital {
asynStatus (*write)(void *drvPvt, asynUser *pasynUser,
epicsUInt32 value, epicsUInt32 mask);
asynStatus (*read)(void *drvPvt, asynUser *pasynUser,
epicsUInt32 *value, epicsUInt32 mask);
asynStatus (*setInterrupt)(void *drvPvt, asynUser *pasynUser,
epicsUInt32 mask, interruptReason reason);
asynStatus (*clearInterrupt)(void *drvPvt, asynUser *pasynUser,
epicsUInt32 mask);
asynStatus (*getInterrupt)(void *drvPvt, asynUser *pasynUser,
epicsUInt32 *mask, interruptReason reason);
asynStatus (*registerInterruptUser)(void *drvPvt, asynUser *pasynUser,
interruptCallbackUInt32Digital callback,void *userPvt,epicsUInt32 mask,
void **registrarPvt);
asynStatus (*cancelInterruptUser)(void *drvPvt, asynUser *pasynUser,
void *registrarPvt);
} asynUInt32Digital;
/*
asynUInt32DigitalBase做了以下方法:
为asynUInt32Digital调用registerInterface。
实现了registerInterruptUser和cancelInterruptUser
提供了所有方法的默认实现。
registerInterruptUser和cancelInterruptUser可以被直接调用,而不是通过queueReqeust。
*/
#define asynUInt32DigitalBaseType "asynUInt32DigitalBase"
typedef struct asynUInt32DigitalBase {
asynStatus (*initialize)(const char *portName,
asynInterface *pasynUInt32DigitalInterface);
} asynUInt32DigitalBase;
epicsShareExtern asynUInt32DigitalBase *pasynUInt32DigitalBase;
asynUInt32Digital
write | 用在value中相应位修改由mask指定的位 |
read | 读取由mask指定的位到值。value的其它位将被设置为0 |
setInterrupt | 为reason设置由mask指定的位到中断 |
clearInterrupt | 清除由mask指定的中断位 |
getInterrupt | 置位为reason启动的mask的每一位。 |
registerInterruptUser | 注册一个回调,当驱动程序探测到由mask指定的任何位中一个变化时,调用这个回调。由于它能够被直接调用,而不是通过queueRequest,这个方法一定不能阻塞。 |
cancelInterruptUser | 取消这个注册的回调。由于它能够被直接调用,而不是通过queueRequest,这个方法一定不能阻塞。 |
asynUInt32DigitalBase是一个接口和相关联代码,它被实现了接口asynUInt32Digital的驱动程序使用。asynUInt32DigitalBase提供了实现了registerInterruptUser和cancelInterruptUser的代码。
asynUInt32DigitalBase
initialize | 在一个驱动程序调用registerPort后,它可以调用 pasynUInt32DigitalBase->initialize(... 在asynInterface中任何空方法被默认实现替代。 |
每个方法的默认实现做以下事情:
asynUInt32Digital
write | 报告一个错误"write is not supported"并且返回一个asynError。 |
read | 报告一个错误"read is not supported"并且返回一个asynError。 |
setInterrupt | 报告一个错误"setInterrupt is not supported"并且返回一个asynError。 |
clearInterrupt | 报告一个错误"clearInterrupt is not supported"并且返回一个asynError。 |
getInterrupt | 报告一个错误"getInterrupt is not supported"并且返回一个asynError。 |
registerInterruptUser | 注册一个interrupt用户。底层驱动程序必须通过对asynManager:interruptStart和asynManager:interruptEnd的调用调用这个注册的回调。 |
cancelInterruptUser | 取消这个回调。 |
七、asynUInt32DigitalSyncIO
asynUInt32DigitalSyncIO描述了一个asynUInt32Digital的同步接口。调用它的代码必须愿意阻塞。
connect | 连接到一个端口和地址,返回一个指向一个asynUser结构体的指针 |
disconnect | 断开连接。这释放了由connect分配的所有资源。 |
write |
调用pasynUInt32Digital->write并且等待这个操作结束或超时。 |
read | 调用pasynUInt32Digital->read并且等待这个操作结束或超时。 |
setInterrupt | 调用pasynUInt32Digital->setInterrupt并且等待这个操作结束或超时。 |
clearInterrupt | 调用pasynUInt32Digital->clearInterrupt并且等待这个操作结束或超时。 |
getInterrupt | 调用pasynUInt32Digital->getInterrupt并且等待这个操作结束或超时。 |
writeOnce, ..., getInterruptOnce | 进行一次连接,(write, ..., getInterrupt),和断开连接。 |
八、asynFloat
asynFloat描述了通过IEEE双精度浮点值进行通信的方法。
typedef void (*interruptCallbackFloat64)(void *userPvt, asynUser *pasynUser,
epicsFloat64 data);
typedef struct asynFloat64Interrupt {
asynUser *pasynUser;
int addr;
interruptCallbackFloat64 callback;
void *userPvt;
} asynFloat64Interrupt;
#define asynFloat64Type "asynFloat64"
typedef struct asynFloat64 {
asynStatus (*write)(void *drvPvt, asynUser *pasynUser, epicsFloat64 value);
asynStatus (*read)(void *drvPvt, asynUser *pasynUser, epicsFloat64 *value);
asynStatus (*registerInterruptUser)(void *drvPvt, asynUser *pasynUser,
interruptCallbackFloat64 callback, void *userPvt,void **registrarPvt);
asynStatus (*cancelInterruptUser)(void *drvPvt, asynUser *pasynUser,
void *registrarPvt);
} asynFloat64;
/* asynFloat64Base做以下事情:
为asynFloat64调用registerInterface.
提供所有方法的默认实现。
registerInterruptUser和cancelInterfaceUser可以直接被调用,而不是通过queueRequest。
*/
#define asynFloat64BaseType "asynFloat64Base"
typedef struct asynFloat64Base {
asynStatus (*initialize)(const char *portName,
asynInterface *pasynFloat64Interface);
} asynFloat64Base;
epicsShareExtern asynFloat64Base *pasynFloat64Base;
asynFloat64
write | 写一个值 |
read | 读一个值 |
registerInterruptUser | 注册一个回调,当新值可用时,它被调用。由于它可以被直接调用,而不是通过queueRequest,这个方法一定不能阻塞。 |
cancelInterruptUser | 取消这个回调。由于它可以被直接调用,而不是通过queueRequest,这个方法一定不能阻塞。 |
asynFloat64Base
initialize | 在一个驱动程序调用registerPort后,它可以调用: pasynFloat64Base->initialize(... 在asynInterface中任何空方法被默认实现替代。 |
每个方法的默认实现做以下事情:
asynFloat64
write | 报告一个错误"write is not supported"并且返回asynError |
read | 报告一个错误"read is not supported"并且返回asynError |
registerInterruptUser | 注册这个中断用户。底层驱动程序必须通过对asynManager:interruptStart和asynManager:interruptEnd的调用调用这个注册的回调。 |
cancelInterruptUser | 取消这个回调 |
九、asynFloat64SyncIO
asynFloat64SyncIO描述一个asynFloat64的同步接口。调用它的代码必须愿意阻塞。
#define asynFloat64SyncIOType "asynFloat64SyncIO"
typedef struct asynFloat64SyncIO {
asynStatus (*connect)(const char *port, int addr,
asynUser **ppasynUser, const char *drvInfo);
asynStatus (*disconnect)(asynUser *pasynUser);
asynStatus (*write)(asynUser *pasynUser,epicsFloat64 value,double timeout);
asynStatus (*read)(asynUser *pasynUser,epicsFloat64 *pvalue,double timeout);
asynStatus (*writeOnce)(const char *port, int addr,
epicsFloat64 value,double timeout,const char *drvInfo);
asynStatus (*readOnce)(const char *port, int addr,
epicsFloat64 *pvalue,double timeout,const char *drvInfo);
} asynFloat64SyncIO;
epicsShareExtern asynFloat64SyncIO *pasynFloat64SyncIO;
asynFloat64SyncIO
connect | 连接到一个端口和地址,返回指向一个asynUser结构体的指针 |
disconnect | 断开连接。它释放由connect分配的所有资源 |
write | 调用pasynFloat64->write并且等待这个操作结束或者超时 |
read | 调用pasynFloat64->read并且等待这个操作结束或者超时 |
writeOnce | 这进行一次连接,write并且断开 |
readOnce | 这进行一次连接,read并且断开 |
十、asynXXXArray(XXX=Int8, Int16, Int32, Int64, Float32或Float64)
asynXXXArray描述了通过8,16,32或64位整数,或者32或64位IEEE浮点值进行通信的方法。
typedef void (*interruptCallbackXXXArray)(
void *userPvt, asynUser *pasynUser,
epicsXXX *data, size_t nelements);
typedef struct asynXXXArrayInterrupt {
asynUser *pasynUser;
int addr;
interruptCallbackXXXArray callback;
void *userPvt;
} asynXXXArrayInterrupt;
#define asynXXXArrayType "asynXXXArray"
typedef struct asynXXXArray {
asynStatus (*write)(void *drvPvt, asynUser *pasynUser,
epicsXXX *value, size_t nelements);
asynStatus (*read)(void *drvPvt, asynUser *pasynUser,
epicsXXX *value, size_t nelements, size_t *nIn);
asynStatus (*registerInterruptUser)(void *drvPvt, asynUser *pasynUser,
interruptCallbackXXXArray callback,
void *userPvt,void **registrarPvt);
asynStatus (*cancelInterruptUser)(void *drvPvt, asynUser *pasynUser,
void *registrarPvt);
} asynXXXArray;
/*
asynXXXArrayBase做以下事情:
为asynXXXArray调用regisgterInterrface。
提供了所有访问的默认实现。
registerInterruptUser和cancelInterruptUser可以被直接调用,而不是通过queueRequest。
*/
#define asynXXXArrayBaseType "asynXXXArrayBase"
typedef struct asynXXXArrayBase {
asynStatus (*initialize)(const char *portName,
asynInterface *pXXXArrayInterface);
} asynXXXArrayBase;
epicsShareExtern asynXXXArrayBase *pasynXXXArrayBase;
asynXXXArray
write | 写一个值的数组 |
read | 读取一个值的数组 |
registerInterruptUser | 注册一个在新数据可用时被调用的回调。 |
cancelInterruptUser | 取消回调 |
asynXXXArrayBase
initialize | 在一个驱动程序调用registerPort后,它可以调用: pasynXXXArrayBase->initialize(... 在asynInterface中任何空方法被默认实现替代 |
每个方法的默认实现做以下事情:
asynXXXArrayBase
write | 报告一个错误"write is not supported"并且返回asynError |
read | 报告一个错误"read is not supported"并且返回asynError |
registerInterruptUser | 注册一个中断回调。 |
cancelInterruptUser | 取消这个中断 |
十一、asynXXXArraySyncIO
asynXXXArraySyncIO描述一个asynXXXArray的同步接口。调用它的代码必须愿意阻塞。
#define asynXXXArraySyncIOType "asynXXXArraySyncIO"
typedef struct asynXXXArraySyncIO {
asynStatus (*connect)(const char *port, int addr,
asynUser **ppasynUser, const char *drvInfo);
asynStatus (*disconnect)(asynUser *pasynUser);
asynStatus (*write)(asynUser *pasynUser, epicsXXX *pvalue,size_t nelem,double timeout);
asynStatus (*read)(asynUser *pasynUser, epicsXXX *pvalue,size_t nelem,size_t *nIn,double timeout);
asynStatus (*writeOnce)(const char *port, int addr,
epicsXXX *pvalue,size_t nelem,double timeout, const char *drvInfo);
asynStatus (*readOnce)(const char *port, int addr,
epicsXXX *pvalue,size_t nelem,size_t *nIn,double timeout, const char *drvInfo);
} asynXXXArraySyncIO;
epicsShareExtern asynXXXArraySyncIO *pasynXXXArraySyncIO;
asynXXXArraySyncIO
connect | 连接到一个端口和地址,返回一个指向一个asynUser的指针 |
disconnect | 断开连接。这释放connect分配的所有资源。 |
write | 调用pasynXXXArray->write并且等待这个操作结束或者超时 |
read | 调用pasynXXXArray->read并且等待这个操作结束或者超时 |
writeOnce | 这进行一次连接,write并且断开连接 |
readOnce | 这进行一次连接,read并且断开连接 |
getBoundsOnce | 这进行一次连接,getBounds并且断开连接 |
十二、asynEnum
asynEnum描述由驱动实现的为设备定义枚举字符串,值以及严重性的方法。
这个接口由驱动程序使用来为EPICS bi,bo,mbbi和mbbo记录设置枚举字符串和值。strings[]用于定义在bi和bo记录中ZNAM和ONAM字段,以及在mbbi和mbbo记录中ZRST,ONST,...FFST字段。由于对于bi和bo记录整数0和1对应ZNAM和ONAM状态,对于bi和bo记录忽略整数values[]。整数values[]用于为mbbi和mbbo记录分配ZRVL,ONVL,...,FFVL字段。整数severities[]用于设置bi和bo记录的ZSV和OSV字段和mbbi和mbbo记录的ZRSV,ONSV,...,FFSV。在write()和read()函数中的nelements参数由客户端使用来指定strings[], values[]和severities[]数组的维度。驱动程序一定不能访问这些数组超过元素nElements-1。在read()中nIn参数被驱动程序使用来设置枚举字符串,值和严重性的实际数目。asynEnum接口没有对字符串施加大小限制。但在bi,bo,mbbo和mbbi记录中字符串字段当前被限制于26个字符。
客户端必须确保在read()函数中strings[]中传递的char *指针要么被设置成NULL或者已经由malloc()分配。如果一个string指针包含一个非NULL值,驱动程序read()函数必须首先调用free()。在复制当前枚举字符串值到它们前,驱动程序必须接着使用malloc()分配这些字符串。
typedef void (*interruptCallbackEnum)
void *userPvt, asynUser *pasynUser,
char *strings[], int values[], int severities[], size_t nelements);
typedef struct asynEnumInterrupt {
asynUser *pasynUser;
int addr;
interruptCallbackEnum callback;
void *userPvt;
} asynEnumInterrupt;
#define asynEnumType "asynEnum"
typedef struct asynEnum {
asynStatus (*write)(void *drvPvt, asynUser *pasynUser,
char *strings[], int values[], int severities[], size_t nelements);
asynStatus (*read)(void *drvPvt, asynUser *pasynUser,
char *strings[], int values[], int severities[], size_t nelements, size_t *nIn);
asynStatus (*registerInterruptUser)(void *drvPvt, asynUser *pasynUser,
interruptCallbackEnum callback, void *userPvt,
void **registrarPvt);
asynStatus (*cancelInterruptUser)(void *drvPvt, asynUser *pasynUser,
void *registrarPvt);
} asynEnum;
/* asynEnumBase does the following:
asynEnumBase做以下事情:
为asynEnum调用registerInterface.
实现了registerInterruptUser和cancelInterruptUser
提供了所有方法的默认实现。
registerInterruptUser和cancelInterruptUser可以被直接调用,而不是通过queueRequest。
*/
#define asynEnumBaseType "asynEnumBase"
typedef struct asynEnumBase {
asynStatus (*initialize)(const char *portName,
asynInterface *pEnumInterface);
} asynEnumBase;
epicsShareExtern asynEnumBase *pasynEnumBase;
asynEnum
write | 写枚举字符串,枚举值和枚举严重性到驱动程序 |
read | 从驱动程序读取枚举字符串,枚举值和枚举严重性 |
registerInterruptUser | 注册一个回调,当有新的枚举字符串,值和严重性时,将调用它。由于它可以被直接调用,而不是通过queueRequest,这个方法一定不能阻塞。 |
cancelInterruptUser | 取消这个调用。由于它可以被直接调用,而不是通过queueRequest,这个方法一定不能阻塞。 |
asynEnumBase是一个接口和相关联代码,它被实现了asynEnum接口的驱动程序使用。asynEnumBase提供了处理registerInterruptUser/cancelInterruptUser的代码。这个驱动程序必须它自己通过对asynManager:interruptStart和asynManager:interruptEnd的调用调用这些回调。
asynEnumBase
initialize | 在一个驱动程序调用registerPort后,它可以调用 pasynEnumBase->initialize(... 在asynInterface中的任何空方法被默认实现替代。 |
每个方法的默认实现做以下事情:
asynEnum
write | 报告一个错误"write is not supported"并且返回asynError |
read | 报告一个错误"read is not supported"并且返回asynError |
registerInterruptUser | 注册一个中断回调 |
cancelInterruptUser | 取消这个回调 |
十三、asynEnumSyncIO
asynEnumSyncIO描述一个asynEnum的同步接口。调用它的代码将愿意阻塞。
#define asynEnumSyncIOType "asynEnumSyncIO"
typedef struct asynEnumSyncIO {
asynStatus (*connect)(const char *port, int addr,
asynUser **ppasynUser, const char *drvInfo);
asynStatus (*disconnect)(asynUser *pasynUser);
asynStatus (*write)(asynUser *pasynUser, char *strings[], int values[], int severities[],
size_t nElements, double timeout);
asynStatus (*read)(asynUser *pasynUser, char *string[], int values[], int severities[],
size_t nElements, size_t *nIn, double timeout);
asynStatus (*writeOnce)(const char *port, int addr, char *strings[], int values[], int severities[],
size_t nElements, double timeout, const char *drvInfo);
asynStatus (*readOnce)(const char *port, int addr, char *strings[], int values[], int severities[],
size_t nElements, size_t *nIn, double timeout, const char *drvInfo);
} asynEnumSyncIO;
epicsShareExtern asynEnumSyncIO *pasynEnumSyncIO;
asynEnumSyncIO
connect | 连接一个端口和地址,返回一个指向一个asynUser的指针 |
disconnect | 断开连接。这释放了由connect分配的所有资源 |
write | 调用pasynEnum->write并且等待这个操作结束或超时 |
read | 调用pasynEnum->read并且等待这个操作结束或超时 |
writeOnce | 这进行一次连接,写和断开连接 |
readOnce | 这进行一次连接,读和断开连接 |
getBoundsOnce | 这进行一次连接,getBounds和断开连接 |
十四、asynGenericPointer
asynGenericPointer描述了一个通过void*指针进行通信的方法。asyn客户端和端口驱动程序必须确认正在被指向的对象的类型是一致的。
typedef void (*interruptCallbackGenericPointer)(void *userPvt, asynUser *pasynUser,
void *pdata);
typedef struct asynGenericPointerInterrupt {
asynUser *pasynUser;
int addr;
interruptCallbackGenericPointer callback;
void *userPvt;
} asynGenericPointerInterrupt;
#define asynGenericPointerType "asynGenericPointer"
typedef struct asynGenericPointer {
asynStatus (*write)(void *drvPvt, asynUser *pasynUser, void *pvalue);
asynStatus (*read)(void *drvPvt, asynUser *pasynUser, void *pvalue);
asynStatus (*registerInterruptUser)(void *drvPvt, asynUser *pasynUser,
interruptCallbackGenericPointer callback, void *userPvt,void **registrarPvt);
asynStatus (*cancelInterruptUser)(void *drvPvt, asynUser *pasynUser,
void *registrarPvt);
} asynGenericPointer;
/*
asynGenericPointerBase做以下事情:
为asynGenericPointer调用registerInterface.
实现了registerInterruptUser和cancelInterruptUser。
提供了所有方法的默认实现。
registerInterruptUser和cancelInterruptUser可以被直接调用,而不是通过queueRequest。
*/
#define asynGenericPointerBaseType "asynGenericPointerBase"
typedef struct asynGenericPointerBase {
asynStatus (*initialize)(const char *portName,
asynInterface *pasynGenericPointerInterface);
} asynGenericPointerBase;
epicsShareExtern asynGenericPointerBase *pasynGenericPointerBase;
asynGenericPointer
write | 写一个值 |
read | 读一个值 |
registerInterruptUser | 注册一个回调,当新数据可用时,调用它。由于它可以被直接调用,而不是通过一个queueRequest,这个方法一定不能阻塞。 |
cancelInterruptUser | 取消这个回调。由于它可以被直接调用,而不是通过一个queueRequest,这个方法一定不能阻塞。 |
asynGenericPointerBase
initialize | 在驱动程序调用registerPort后,它可以调用: pasynGenericPointBase->initialize(... 在asynInterface中任何空方法被默认实现替代。 |
每个方法的默认实现做以下事情:
write | 报告一个错误"write is not supported"并且返回asynError |
read | 报告一个错误"read is not supported"并且返回asynError |
registerInterruptUser | 注册这个中断用户。底层驱动程序必须通过对asynManager:interruptStart和asynManager:interruptEnd的调用调用这个注册的回调。 |
cancelInterruptUser | 取消这个回调 |
十五、asynGenericPointerSyncIO
asynGenericPointerSyncIO描述asynGenericPointer的同步接口。调用它的代码必须愿意阻塞。
#define asynGenericPointerSyncIOType "asynGenericPointerSyncIO"
typedef struct asynGenericPointerSyncIO {
asynStatus (*connect)(const char *port, int addr,
asynUser **ppasynUser, const char *drvInfo);
asynStatus (*disconnect)(asynUser *pasynUser);
asynStatus (*write)(asynUser *pasynUser,void *pvalue,double timeout);
asynStatus (*read)(asynUser *pasynUser,void *pvalue,double timeout);
asynStatus (*writeRead)(asynUser *pasynUser,void *pwrite_buffer,void *pread_buffer,double timeout);
asynStatus (*writeOnce)(const char *port, int addr,
void *pvalue,double timeout,const char *drvInfo);
asynStatus (*readOnce)(const char *port, int addr,
void *pvalue,double timeout,const char *drvInfo);
asynStatus (*writeReadOnce)(const char *port, int addr,
void *pwrite_buffer,void *pread_buffer,double timeout,const char *drvInfo);
} asynGenericPointerSyncIO;
epicsShareExtern asynGenericPointerSyncIO *pasynGenericPointerSyncIO;
asynGenericPointerSyncIO
connect | 连接一个端口和地址,返回一个指向一个asynUser结构体的指针 |
disconnect | 断开连接。这释放由connect分配的所有资源 |
write | 调用pasynGenericPointer->write并且等待这个操作结束或超时 |
read | 调用pasynGenericPointer->read并且等待这个操作结束或超时 |
writeRead | 调用pasynGenericPointer->write,接着pasynGenericPointer->read并且等待这些操作结束或超时 |
writeOnce | 这进行一次连接,写和断开连接 |
readOnce | 这进行一次连接,读和断开连接 |
writeReadOnce | 这进行一次连接,writeRead和断开连接 |