此示例展示了从asynPortDriver继承的驱动程序的编写过程,以及演示了在记录中asynInt32, asynUInt32Digital和asynFloat64接口的使用方法。
1、驱动程序源代码:
Readback.h:
/*
* 从asynPortDriver类继承的asyn驱动
* 用常见的扫描和I/O Intr扫描测试错误处理
*/
# include "asynPortDriver.h"
/* 这些是drvInfo字符串,用于标识参数。asyn客户端使用它们, 包含表征的asyn设备支持*/
#define P_Int32ValueString "INT32_VALUE" /* asynInt32 */
#define P_BinaryInt32ValueString "BINARY_INT32_VALUE" /* asynInt32 */
#define P_MultibitInt32ValueString "MULTIBIT_INT32_VALUE" /* asynInt32 */
#define P_Float64ValueString "FLOAT64_VALUE" /* asynFloat64 */
#define P_UInt32DValueString "UINT32D_VALUE" /* asynUInt32Digital*/
#define P_BinaryUInt32DValueString "BINARY_UINT32D_VALUE" /* asynUInt32Digital*/
#define P_MultibitUInt32DValueString "MULTIBIT_UINT32D_VALUE"/* asynUInt32Digital*/
#define P_InitialStateString "INITIAL_STATE" /* asynInt32 */
#define P_StartCountString "START_COUNT" /* asynInt32 */
class Readback: public asynPortDriver{
public:
Readback(const char * portName, int initialReadStatus);
virtual asynStatus readInt32(asynUser * pasynUser, epicsInt32 * value);
virtual asynStatus readFloat64(asynUser * pasynUser, epicsFloat64 * value);
virtual asynStatus readUInt32Digital(asynUser * pasynUser, epicsUInt32 * value, epicsUInt32 mask);
virtual asynStatus writeInt32(asynUser * pasyUser, epicsInt32 value);
void startThread(void);
protected:
/* 用于pasynUser->reason的值,以及对参数库的索引 */
int P_Int32Value;
int P_BinaryInt32Value;
int P_MultibitInt32Value;
int P_Float64Value;
int P_UInt32DValue;
int P_BinaryUInt32DValue;
int P_MultibitUInt32DValue;
int P_InitialStateValue;
int P_StartCountValue;
private:
/* 我们的数据 */
asynStatus initialReadStatus_;
epicsEventId startCount_;
};
Readback.cpp:
#include "epicsThread.h"
#include "epicsTypes.h"
#include "iocsh.h"
#include "Readback.h"
#include "epicsExport.h"
#define UINT32_DIGITAL_MASK 0xFFFFFFFF
static void startThreadC(void * pvt);
/*
Readback类的基类
调用asynPortDriver基类的构造器。
[in] portName:要创建的asyn端口驱动的名称。
*/
Readback::Readback(const char * portName, int initialReadStauts)
:asynPortDriver(portName,
1,
asynInt32Mask | asynFloat64Mask |asynUInt32DigitalMask | asynDrvUserMask,
asynInt32Mask | asynFloat64Mask |asynUInt32DigitalMask,
0,
1,
0,0), initialReadStatus_((asynStatus)initialReadStauts)
{
int status;
/*create paramteters in the parameter library*/
createParam(P_Int32ValueString, asynParamInt32, &P_Int32Value);
createParam(P_BinaryInt32ValueString, asynParamInt32, &P_BinaryInt32Value);
createParam(P_MultibitInt32ValueString, asynParamInt32, &P_MultibitInt32Value);
createParam(P_Float64ValueString, asynParamFloat64, &P_Float64Value);
createParam(P_UInt32DValueString, asynParamUInt32Digital, &P_UInt32DValue);
createParam(P_BinaryUInt32DValueString, asynParamUInt32Digital, &P_BinaryUInt32DValue);
createParam(P_MultibitUInt32DValueString, asynParamUInt32Digital, &P_MultibitUInt32DValue);
createParam(P_InitialStateString, asynParamInt32, &P_InitialStateValue);
createParam(P_StartCountString, asynParamInt32, &P_StartCountValue);
setIntegerParam (P_Int32Value, 10);
setParamStatus (P_Int32Value, asynSuccess);
setIntegerParam (P_BinaryInt32Value, 1);
setParamStatus (P_BinaryInt32Value, asynSuccess);
setIntegerParam (P_MultibitInt32Value, 3);
setParamStatus (P_MultibitInt32Value, asynSuccess);
setIntegerParam (P_StartCountValue, 0);
setDoubleParam (P_Float64Value, 6.6);
setParamStatus (P_Float64Value, asynSuccess);
setUIntDigitalParam (P_UInt32DValue, (epicsUInt32)0xFF, UINT32_DIGITAL_MASK, UINT32_DIGITAL_MASK);
setParamStatus (P_UInt32DValue, asynSuccess);
setUIntDigitalParam (P_BinaryUInt32DValue, (epicsUInt32)0x01, UINT32_DIGITAL_MASK, UINT32_DIGITAL_MASK);
setParamStatus (P_BinaryUInt32DValue, asynSuccess);
setUIntDigitalParam (P_MultibitUInt32DValue, (epicsUInt32)0x03, UINT32_DIGITAL_MASK, UINT32_DIGITAL_MASK);
setParamStatus (P_MultibitUInt32DValue,asynSuccess);
setIntegerParam (P_InitialStateValue, initialReadStatus_);
startCount_ = epicsEventMustCreate(epicsEventEmpty);
status = (epicsThreadCreate("startThreadC", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium),
(EPICSTHREADFUNC)::startThreadC, (void *)this) == NULL);
if (status ){
printf("%s: %s epicsThreadCreate failed\n", "Readback", "startThreadC");
return;
}
}
void Readback::startThread()
{
epicsInt32 int32, binaryInt32, multibitInt32;
epicsUInt32 uint32d, binaryuint32d, multibituint32d;
epicsFloat64 float64;
lock();
while (1){
unlock();
epicsEventMustWait(startCount_);
lock();
getIntegerParam(P_Int32Value,
if (int32 > 1000){
int32 = 0;
}
else{
int32 += 1;
}
setIntegerParam(P_Int32Value, int32);
getIntegerParam(P_BinaryInt32Value, &binaryInt32);
if (binaryInt32 == 0){
binaryInt32 = 1;
}
else{
binaryInt32 = 0;
}
setIntegerParam(P_BinaryInt32Value, binaryInt32);
getIntegerParam(P_MultibitInt32Value, &multibitInt32);
if (multibitInt32 > 3){
multibitInt32 = 0;
}
else{
multibitInt32 += 0;
}
setIntegerParam(P_MultibitInt32Value, multibitInt32);
getDoubleParam(P_Float64Value,
if (float64 > 100){
float64 = 0;
}
else{
float64 += 0.5;
}
setDoubleParam(P_Float64Value, float64);
getUIntDigitalParam (P_UInt32DValue, &uint32d , UINT32_DIGITAL_MASK);
if (uint32d == 0xFF){
uint32d = 0;
}
else{
uint32d += 1;
}
setUIntDigitalParam(P_UInt32DValue, uint32d & 0xFF , UINT32_DIGITAL_MASK, UINT32_DIGITAL_MASK);
getUIntDigitalParam(P_BinaryUInt32DValue, &binaryuint32d, UINT32_DIGITAL_MASK);
if (binaryuint32d){
binaryuint32d = 0;
}
else{
binaryuint32d = 1;
}
setUIntDigitalParam(P_BinaryUInt32DValue, binaryuint32d & 0x1, UINT32_DIGITAL_MASK, UINT32_DIGITAL_MASK );
getUIntDigitalParam(P_MultibitUInt32DValue, &multibituint32d, UINT32_DIGITAL_MASK);
if (multibituint32d == 3){
multibituint32d = 0;
}
else{
multibituint32d += 1;
}
setUIntDigitalParam(P_MultibitUInt32DValue, multibituint32d & 0x3, UINT32_DIGITAL_MASK, UINT32_DIGITAL_MASK);
callParamCallbacks();
epicsThreadSleep(0.2);
}
}
asynStatus Readback::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
int function = pasynUser->reason;
if (function == P_InitialStateValue){
initialReadStatus_= (asynStatus)value;
setIntegerParam(P_InitialStateValue, value);
callParamCallbacks();
return asynSuccess;
}
else{
if (function == P_StartCountValue){
if (value > 0){
epicsEventSignal(startCount_);
}
}
return asynPortDriver::writeInt32(pasynUser, value);
}
}
asynStatus Readback::readInt32(asynUser *pasynUser, epicsInt32 *value)
{
// printf("In Readback:readInt32: initialReadStatus_ = %d\n", initialReadStatus_);
if (initialReadStatus_){
return initialReadStatus_;
}
return asynPortDriver::readInt32(pasynUser, value);
}
asynStatus Readback::readFloat64(asynUser * pasynUser, epicsFloat64 * value)
{
if (initialReadStatus_){
return initialReadStatus_;
}
return asynPortDriver::readFloat64(pasynUser, value);
}
asynStatus Readback::readUInt32Digital(asynUser * pasynUser, epicsUInt32 * value, epicsUInt32 mask)
{
if (initialReadStatus_){
return initialReadStatus_;
}
return asynPortDriver::readUInt32Digital(pasynUser, value, mask);
}
static void startThreadC(void *pvt)
{
Readback * preadback = (Readback *)pvt;
preadback->startThread();
}
extern "C"{
int ReadbackConfigure(const char * portName, int initialReadStauts)
{
new Readback(portName, initialReadStauts);
return asynSuccess;
}
/* EPICS iocsh shell command */
static const iocshArg initArg0 = {"portName", iocshArgString};
static const iocshArg initArg1 = {"initialReadStatus", iocshArgInt};
static const iocshArg * const initArgs[] = {&initArg0,
static iocshFuncDef initFuncDef = {"ReadbackConfigure", 2, initArgs};
static void initCallFunc(const iocshArgBuf * args)
{
ReadbackConfigure(args[0].sval, args[1].ival);
}
void ReadbackRegister(void)
{
iocshRegister(&initFuncDef, initCallFunc);
}
epicsExportRegistrar(ReadbackRegister);
}
2、对应的数据库文件:
1)使用asynInt32接口的数据库记录文件useasynInt32.db:
record(longout, "$(P)StartCount")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))START_COUNT")
info(asyn:READBACK, "1")
}
record(longin, "$(P)InitialStateIn")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INITIAL_STATE")
field(SCAN, "$(SCAN)")
}
record(longout, "$(P)InitialState")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INITIAL_STATE")
}
record(longout, "$(P)InitialStateRB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INITIAL_STATE")
info(asyn:READBACK, "1")
}
record(ao, "$(P)AoInt32")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
}
record(ao, "$(P)AoInt32RB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
info(asyn:READBACK,"1")
}
record(ai, "$(P)AiInt32")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
field(SCAN, "$(SCAN)")
}
record(ai, "$(P)AiInt32TS")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
field(SCAN, "$(SCAN2)")
}
record(longout, "$(P)LongoutInt32")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
}
record(longout, "$(P)LongoutInt32RB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
info(asyn:READBACK,"1")
}
record(longin, "$(P)LonginInt32")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
field(SCAN, "$(SCAN)")
}
record(longin, "$(P)LonginInt32TS")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
field(SCAN, "$(SCAN2)")
}
record(bo, "$(P)BoInt32")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))BINARY_INT32_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(bo, "$(P)BoInt32RB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))BINARY_INT32_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
info(asyn:READBACK,"1")
}
record(bi, "$(P)BiInt32")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))BINARY_INT32_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
field(SCAN, "$(SCAN)")
}
record(bi, "$(P)BiInt32TS")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))BINARY_INT32_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
field(SCAN, "$(SCAN2)")
}
record(mbbo, "$(P)MbboInt32")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))MULTIBIT_INT32_VALUE")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
field(FRST, "State 4")
field(FRVL, "4")
field(FVST, "State 5")
field(FVVL, "5")
}
record(mbbo, "$(P)MbboInt32RB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))MULTIBIT_INT32_VALUE")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
field(FRST, "State 4")
field(FRVL, "4")
field(FVST, "State 5")
field(FVVL, "5")
info(asyn:READBACK,"1")
}
record(mbbi, "$(P)MbbiInt32")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))MULTIBIT_INT32_VALUE")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
field(FRST, "State 4")
field(FRVL, "4")
field(FVST, "State 5")
field(FVVL, "5")
field(SCAN, "$(SCAN)")
}
record(mbbi, "$(P)MbbiInt32TS")
{
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))MULTIBIT_INT32_VALUE")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
field(FRST, "State 4")
field(FRVL, "4")
field(FVST, "State 5")
field(FVVL, "5")
field(SCAN, "$(SCAN2)")
}
2) 使用asynFloat64接口的useasynFloat64.db数据库记录文件:
###################################################################
# Records that use devAsynFloat64 #
###################################################################
record(ao, "$(P)AoFloat64")
{
field(PINI, "$(PINI)")
field(DTYP, "asynFloat64")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLOAT64_VALUE")
field(PREC, "1")
}
record(ao, "$(P)AoFloat64RB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynFloat64")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLOAT64_VALUE")
field(PREC, "1")
info(asyn:READBACK,"1")
}
record(ai, "$(P)AiFloat64")
{
field(DTYP, "asynFloat64")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLOAT64_VALUE")
field(PREC, "1")
field(SCAN, "$(SCAN)")
}
record(ai, "$(P)AiFloat64TS")
{
field(DTYP, "asynFloat64")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLOAT64_VALUE")
field(PREC, "1")
field(SCAN, "$(SCAN2)")
}
3) 使用asynUInt32Digital接口的数据库记录文件 useasynUInt32Digital.db:
###################################################################
# Records that use devAsynUInt32Digital #
###################################################################
record(longout, "$(P)LongoutUInt32D")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask($(PORT),$(ADDR),0x000000FF, $(TIMEOUT))UINT32D_VALUE")
}
record(longout, "$(P)LongoutUInt32DRB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask($(PORT),$(ADDR),0x000000FF, $(TIMEOUT))UINT32D_VALUE")
info(asyn:READBACK,"1")
}
record(longin, "$(P)LonginUInt32D")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x000000FFF, $(TIMEOUT))UINT32D_VALUE")
field(SCAN, "$(SCAN)")
}
record(longin, "$(P)LonginUInt32DTS")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x000000FFF, $(TIMEOUT))UINT32D_VALUE")
field(SCAN, "$(SCAN2)")
}
record(bo, "$(P)BoUInt32D")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask($(PORT),$(ADDR),0x1, $(TIMEOUT))BINARY_UINT32D_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(bo, "$(P)BoUInt32DRB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask($(PORT),$(ADDR),0x1, $(TIMEOUT))BINARY_UINT32D_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
info(asyn:READBACK,"1")
}
record(bi, "$(P)BiUInt32D")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x1, $(TIMEOUT))BINARY_UINT32D_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
field(SCAN, "$(SCAN)")
}
record(bi, "$(P)BiUInt32DTS")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x1, $(TIMEOUT))BINARY_UINT32D_VALUE")
field(ZNAM, "Zero")
field(ONAM, "One")
field(SCAN, "$(SCAN2)")
}
record(mbbo, "$(P)MbboUInt32D")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
field(OUT, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
}
record(mbbo, "$(P)MbboUInt32DRB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
info(asyn:READBACK,"1")
}
record(mbbi, "$(P)MbbiUInt32D")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
field(SCAN, "$(SCAN)")
}
record(mbbi, "$(P)MbbiUInt32DTS")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
field(ZRST, "State 0")
field(ZRVL, "0")
field(ONST, "State 1")
field(ONVL, "1")
field(TWST, "State 2")
field(TWVL, "2")
field(THST, "State 3")
field(THVL, "3")
field(SCAN, "$(SCAN2)")
}
record(mbboDirect, "$(P)MbboDUInt32D")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
}
record(mbboDirect, "$(P)MbboDUInt32DRB")
{
field(PINI, "$(PINI)")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
info(asyn:READBACK,"1")
}
record(mbbiDirect, "$(P)MbbiDUInt32D")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
field(SCAN, "$(SCAN)")
}
record(mbbiDirect, "$(P)MbbiDUInt32DTS")
{
field(DTYP, "asynUInt32Digital")
field(INP, "@asynMask($(PORT),$(ADDR),0x3, $(TIMEOUT))MULTIBIT_UINT32D_VALUE")
field(SCAN, "$(SCAN2)")
}
3) 启动脚本st.cmd如下:
...
ReadbackConfigure("MYPORT", 0)
## Load record instances
# useasynFloat64.db useasynInt32.db useasynUInt32Digital.db
dbLoadRecords("db/useasynInt32.db","P=Readback:,PORT=MYPORT,ADDR=0,TIMEOUT=1,SCAN=I/O Intr,SCAN2=1 second,PINI=NO")
dbLoadRecords("db/useasynFloat64.db","P=Readback:,PORT=MYPORT,ADDR=0,TIMEOUT=1,SCAN=I/O Intr,SCAN2=1 second,PINI=NO")
dbLoadRecords("db/useasynUInt32Digital.db","P=Readback:,PORT=MYPORT,ADDR=0,TIMEOUT=1,SCAN=I/O Intr,SCAN2=1 second,PINI=NO")
...