EPICS-- asyn模块-- asynDriver4--EPICS记录的通用设备支持

为标准的EPICS记录提供了通用的设备支持。这个支持应该对一大类底层基于寄存器的驱动程序有用。对于复杂的设备,需要其它支持。这个发行版提供了以下:

  • devAsynInt32:对实现了接口asynInt32的驱动程序的支持
  • devAsynInt64:对实现了接口asynInt64的驱动程序的支持
  • devAsynInt32TimeSeries:对实现了在接口asynInt32上回调的驱动程序的waveform记录支持
  • devAsynInt64TimeSeries:对实现了在接口asynInt64上回调的驱动程序的waveform记录支持
  • devAsynInt8Array:对实现了接口asynInt8Array的驱动程序的支持
  • devAsynInt16Array:对实现了接口asynInt16Array的驱动程序的支持
  • devAsynInt32Array:对实现了接口asynInt32Array的驱动程序的支持
  • devAsynInt64Array:对实现了接口asynInt64Array的驱动程序的支持
  • devAsynUInt32Digital:对实现了接口asynUInt32Digital的驱动程序的支持
  • devAsynFloat64:对实现了接口asynFloat64的驱动程序的支持
  • devAsynFloat64TimeSeries:对实现了在接口asynFloat64上回调的驱动程序的waveform记录支持。
  • devAsynFloat32Array:对实现了接口asynFloat32Array的驱动程序的支持。
  • devAsynFloat64Array:对实现了接口asynFloat64Array的驱动程序的支持。
  • devAsynOctet:对实现了接口asynOctet的驱动程序的支持。
  • devEpics:这只是一个文件devEpics.dbd,它包含了对应以上支持的dbd文件。
  • asynEpicsUtils.c:这提供功能函数。parseLInk(), parseLinkMask()和parseLinkFree()解析以上描述的记录INP和OUT链接。asynStatusToEpicsAlarm()转换asynStatus枚举值到EPICS记录STAT和SEVR值设置记录警报。

这个支持对DTYP和INP使用以下规则。OUT字段与INP相同。

 field(DTYP,"asynXXX")
 field(INP,"@asyn(portName,addr,timeout)drvParams")
 or
 field(INP,"@asynMask(portName,addr,mask,timeout)drvParams")

此处:

  • XXX:支持的接口类型的名称

  • portName:port的名称

  • addr:地址。如果不支持addr,默认是0

  • mask:这是用于devAsynUInt32Digital。它也被devAsynInt32使用来为不支持getBounds()的驱动程序指定硬件设备的位数。

  • timeout:用于asynUser.timeout的超时值。如果未被指定,默认是1.0

  • drvParms:这是通过asynDrvUser接口被传递给底层驱动程序。

例如:

field(DTYP,"asynInt32")
field(INP,"@asyn(portA,0,.1)thisIsForDriver")

1) asynManager中断和EPICS设备支持

所有这些设备支持文件可以未输入记录调用registerInterruptUser。用两种方法之一调用这个回调:

1) 除了Average和TimeSeries外的输入记录

使用它支持SCAN="I/O Intr"。

2) 被平均的输入记录,即:asynInt32Average或asynFloat64Average

这些记录可以被周期地或者用SCAN=I/O Intr扫描。registerInterruptUser回调用于在记录运行之间把当前值加到值的和。

如果这个记录被周期地扫描,接着在这个记录每次运行时计算这个平均。如果在新数据到达前(numAverage)前,这个记录被运行,这个记录被设置为UDF/INVALID,UDF被设置成TRUE,并且值保留不变。

如果记录设置了SCAN=I/O Intr,则每次NumAverage回调读取已经被接收到时,计算这个平均并且运行这个记录。在ai记录中地SVAL字段被用于设置NumAverage。这是非常聪明的,但没有另一种好方法当允许值在运行时被修改时传递此值给设备。这意味着如果SCAN=I/O Intr,仿真模式不能与asynInt32Average或asynFloat64Average设备支持一起使用。这可能不是一个重要限制。在R4-34中添加了对SCAN=I/O Intr的支持。

3) 是waveform时间序列的输入记录,即:asynInt32TimeSeries, asynInt64TimeSeries或asynFloat64TimeSeries。

这些记录通常被周期地扫描。registerInterruptUser回调用于向这个时间序列追加值。

2) 输出记录地初始值

在基于寄存器接口上的输出记录的设备支持(bo, mbbo, ao, longout)在init_record中进行了一次从这个驱动程序初始值的read()。如果这个read()返回asynSuccess,则记录值被设置成从read()返回的值。如果read()返回除了asynSuccess外的其它东西,则这个记录值被修改。这种机制支持"bumpless reboot",在这种情况中,当IOC启动时,输出记录的初始值将匹配硬件的当前值。仅在这个值已经有效时,驱动程序才从read()函数返回asynSuccess。注意:当iocInit启动时,从设备读取的这个值将替代在数据库中的值。然而,从设备读取的值可能接着被来自save/restore的任何值替代,因为自动恢复在iocInit中靠后发生。

从R4-30开始,devAsynOctet被更改成也对stringout和waveform输出记录支持初始回读。如果在数据库中的记录包含以下行,才进行初始回读:

info(asyn:INITIAL_READBACK, "1")

3) bi, bo, mbbi和mbbo记录的枚举值

从asyn R4-19开始,为asyn端口驱动程序增加了在bi, bo,mbbi和mbbo记录中控制枚举字符串,枚举值和枚举严重性的值的支持。在asynInt32和asynUInt32Digital设备支持实现了这个支持:

  • 在设备支持init_record函数中,设备支持尝试在驱动程序中查找asynEnum接口。如果找到了它,调用pasynEnumSyncIO->read()从这个驱动程序读取枚举的当前值。如果read()返回asynSuccess,则枚举字段被设置成由驱动程序返回的值。如果不支持asynEnum,或者如果read()返回除asynSuccess外的任何东西,则枚举字段不被修改。
  • 设备支持注册在asynEnum接口上的回调。驱动程序在运行时进行回调来动态更改枚举的值。例如,更改一个ADC的增益会更改用于速度等的可用选项。当枚举字段变化,设备支持调用db_post_events(pr, &pr->val, DBE_PROPERTY)。这通知客户端这个枚举值已经变化。老的如medm和edm的客户端在窗口被关闭并重新打开前将不会更改枚举小部件,但像CSS的较新客户端会动态地更改这个枚举小部件。

4) 输出记录地回调更新

从asyn R4-26开始,添加了对从驱动程序中断回调更新输出记录地支持。这种特性允许输出记录反映由手动前端面板操作引起的下层硬件中地变化,由另一个输出记录引起的变化等。

默认,在一个驱动程序进行中断回调时,输出记录不更新。但,如果为在数据库文件中一个记录添加以下info标签,则回调将被启用,并且在驱动程序为那个值进行一个回调时,将更新输出记录。

info(asyn:READBACK, "1")

如果info标签的值是0或者如果info标签没有出现,则禁用在中断回调上输出记录的更新。

5) 驱动程序回调的缓存

驱动程序回调之间的时间短于记录运行的时间是可能的。asyn设备支持提供一个环形缓存(FIFO)机制来缓存值,使得记录将处理来自短暂一阵回调的所有回调值。对于除了stringin, stringout和waveform记录外的所有记录,默认缓存尺寸是10个值。对于stringin, stringout和waveform记录,默认缓存尺寸是0,即:没有缓存。对于所有记录类型,对于在数据库文件中一个记录,缓存的尺寸可以受控于以下info标签:

info(asyn:FIFO, "20")

在这个示例中,缓存尺寸被设置为20。在asyn R4-10中,为除了stringin, stringout和waveform外的所有记录添加了环形缓存支持。在asyn R4-25中,添加了对数值数组的waveform记录支持。在asyn R4-26中添加了对stringin, stringout和waveform记录的asynOctet支持。在R4-35中,发现了asyn:READBACK的死锁问题。要用asynOctet输出记录修复这个问题,需要一个环形缓存。因而,即使不指定asyn:FIFO,为asyn:READBACK=1的这些记录,在驱动程序中执行了一个1的最小环形尺寸。asyn:FIFO仍然可用于选择一个更大的环形缓存尺寸。

6) 时间戳

从asyn R4-20开始,为asyn端口驱动程序增加了设置输入记录的TIME字段的支持。通过设置这个记录的TSE字段为"-2",并且在设备读取方法或中断回调中设置所需值到被指向的pasynUser结构体的时间戳字段中。

从asyn R4-22开始,向asynManager添加了时间戳支持函数来为在asynManager中端口更新,获取和设置最近时间戳。为用户提供的时间戳源函数增加了支持。向为基类读取函数和回调函数的asynPortDriver增加了时间戳支持。

7) asynInt32设备支持

以下支持是可用的:

device(ai,INST_IO,asynAiInt32,"asynInt32")
device(ai,INST_IO,asynAiInt32Average,"asynInt32Average")
device(ao,INST_IO,asynAoInt32,"asynInt32")
device(bi,INST_IO,asynBiInt32,"asynInt32")
device(bo,INST_IO,asynBoInt32,"asynInt32")
device(mbbi,INST_IO,asynMbbiInt32,"asynInt32")
device(mbbo,INST_IO,asynMbboInt32,"asynInt32")
device(longin,INST_IO,asynLiInt32,"asynInt32")
device(longout,INST_IO,asynLoInt32,"asynInt32")

devAsynInt32.c为实现了接口asynInt32的驱动程序提供了EPICS设备支持。

对于ai和ao记录,可以使用以下任何一种用于INP和OUT字段的格式:

field(INP,"@asyn(portName,addr,timeout) drvParams")
field(INP,"@asynMask(portName,addr,nbits,timeout) drvParams")

asynMask格式允许设备支持使用由于其不知道设备范围而不能从getBounds()返回有意义值得驱动程序。例如,这对Modbus ADCs是真的。按如下定义nbits参数:

1)nbits>0:设备是范围从0到2^(nbits)的单极性。值将被掩饰成指定的位数。

2) nbits<0:设备时范围从-2^(abs(nbits)-1)到2^(abs(nbits)-1)范围的双极性。使用符号位符号扩展用asynInt32接口读取的值(例如:从第0位开始到第abs(nbits)-1位)。

记录

1)aiRecord

一个值被传递给rval。如果驱动程序实现了getBounds或者按以上解释制定了nbits,支持线性转换。

  • asynInt32:支持"SCAN I/O Intr"。如果这个记录是"I/O Intr"被扫描的,则当registerInterruptUser回调被调用,它保存了这个值并且调用scanIoReqeuest。当这个记录被运行,被保存的值被放入rval。如果这个记录不是"I/O Intr"被扫描的,则每次运行这个记录时,通过对pasynInt32->read的调用,读取一个新值。
  • asynInt32Average:reigsterIntrruptUser回调添加这个新值到一个和并且增加采样数目。当这个记录被运行,计算平均并且和与采样数目都被设为0。如果这个记录在新数据到达前(numAverage==0)被运行了,这个记录被设置位UDF/INVALID,UDF被设置位TRUE,并且这个值保留不变。可以周期地或者用SCAN=I/O Intr扫描这个记录。如果这个记录设置成SCAN=I/O Intr,则每次NumAverage回调读取已经被接收时,计算这个平均并且运行这个记录。在ai记录中SVAL字段用于设置NumAverage。

2)aoRecord:rval被写。如果驱动程序实现了getBounds或者如果按如上解释指定了nbits,支持线性转换。

3)  longinRecord:一个值传给了val。每次运行这个记录时,读取一个新值。类似aiRecord,支持"I/O Intr"。

4) longoutRecrod:val被写。

5) biRecord:一个值传给rval。在这个记录中不使用mask字段。每次运行这个记录时,读取一个新值。类似aiRecord,支持"I/O Intr"。

6) boRecord:rval被写。在这个记录中不使用掩码字段。

7)mbbiRecord:一个值传给了rval。从nobt和shft计算出一个掩码。每次运行这个记录时,读取一个新值。类似aiRecord,支持"I/O Intr"。

8) mbboRecord:rval被写。从nobt和shft计算掩码。

模拟输入示例记录

 record(ai,"aiInt32") {
        field(SCAN,"I/O Intr")
        field(DTYP,"asynInt32")
        field(INP,"@asyn($(port),$(addr))")
        field(EGUF,"10.0")
        field(EGUL,"-10.0")
        field(PREC,"3")
   }
   # This record is for a 12-bit bipolar ADC for a driver that does not
   # support getBounds()
   record(ai,"aiInt32") {
        field(SCAN,"I/O Intr")
        field(DTYP,"asynInt32")
        field(INP,"@asynMask($(port),$(addr),-12)")
        field(EGUF,"10.0")
        field(EGUL,"-10.0")
        field(PREC,"3")
   }
   record(ai,"aiInt32Average") {
        field(SCAN,"10 second")
        field(DTYP,"asynInt32Average")
        field(INP,"@asyn($(port),$(addr))")
        field(EGUF,"10.0")
        field(EGUL,"-10.0")
        field(PREC,"3")
   }

模拟输出示例记录

   record(ao,"aoInt32") {
        field(DTYP,"asynInt32")
        field(OUT,"@asyn($(port),$(addr))")
        field(EGUF,"10.0")
        field(EGUL,"-10.0")
        field(PREC,"3")
   }

长整数输入示例记录

record(longin,"liInt32") {
        field(SCAN,"I/O Intr")
        field(DTYP,"asynInt32")
        field(INP,"@asyn($(port),$(addr))")
}

长整数输出示例记录

record(longout,"loInt32") {
        field(DTYP,"asynInt32")
        field(OUT,"@asyn($(port),$(addr))")
}

多位二进制输入示例记录

 record(mbbi,"mbbiInt32") {
        field(SCAN,"I/O Intr")
        field(DTYP,"asynInt32")
        field(INP,"@asyn($(port),$(addr))")
        field(NOBT,"2")
        field(SHFT,"2")
        field(ZRST,"zeroVal")
        field(ONST,"oneVal")
        field(TWST,"twoVal")
        field(THST,"threeVal")
 }

多位二进制输出示例记录

record(mbbo,"mbboInt32") {
        field(DTYP,"asynInt32")
        field(OUT,"@asyn($(port),$(addr))")
        field(NOBT,"2")
        field(SHFT,"16")
        field(ZRST,"zeroVal")
        field(ONST,"oneVal")
        field(TWST,"twoVal")
        field(THST,"threeVal")
}

8) asynInt64设备支持

asynInt64设备支持可用于所有版本EPICS base的ao,ai,longout和longin记录。以下支持在devAsynInt64Misc.dbd中获取。

device(longin,INST_IO,asynLiInt64,"asynInt64")
device(longout,INST_IO,asynLoInt64,"asynInt64")
device(ai,INST_IO,asynAiInt64,"asynInt64")
device(ao,INST_IO,asynAoInt64,"asynInt64")

在EPICS base 3.16.1及以上中,对int64in, int64out和waveform的支持可以获取。那是添加了int64in, int64out记录的版本,并且waveform记录添加了对FTVL=Int64的支持。以下支持在devAsynInt64.dbd中可以获取:

device(int64in,INST_IO,Int64Out,"asynInt64")
device(int64out,INST_IO,Int64Out,"asynInt64")

devAsynInt64.c为实现了接口asynInt64的驱动程序提供了EPICS设备支持。

1) aiRecord:从驱动程序读取一个64位整数并且转成一个64位浮点。64位浮点可以完全表示最多52位整数。值被读取到.VAL字段,不是.RVAL字段。线性转换被限制于.EOFF和.ESLO。每次记录运行时,读取一个新值。支持SCAN "I/O Intr"。

2) aoRecord:64位浮点 .VAL被转成一个64位整数并且被写到驱动程序。64位浮点可以完全表示最多52位的整数。从.VAL读取这个值,而不是.RVAL字段。线性转换被限制于.EOFF和.ESLO。

3) longinRecord:从驱动程序读取一个64位整数,并且被截短到一个32位整数。每次运行则个记录,读取一个新值。支持SCAN "I/O Intr"。

4) longoutRecord:一个32位整数被从.VAL字段写到驱动程序。

5) int64inRecord:一个值传给.VAL。每次运行这个记录时,读取一个新值。类似aiRecord支持"I/O Intr"。

6) int64outRecord:.VAL被写。

Int64输入示例记录。longin和ai记录除了记录类型外是相同的。

record(int64in,"Int64In") {
        field(SCAN,"I/O Intr")
        field(DTYP,"asynInt64")
        field(INP,"@asyn($(port),$(addr))")
}

Int64输出示例记录。longout和ao记录除了记录类型外是相同的。

 record(int64out,"Int64Out") {
        field(DTYP,"asynInt64")
        field(OUT,"@asyn($(port),$(addr))")
 }

9) asynIntXXXArray设备支持(XXX=8, 16, 32或64)

以下支持可用:

device(waveform,INST_IO,asynIntXXXArrayWfIn,"asynIntXXXArrayIn")
device(waveform,INST_IO,asynIntXXXArrayWfOut,"asynIntXXXArrayOut")

devAsynIntXXXArray.c提供了实现接口asynIntXXXArray的驱动程序的EPICS设备支持。它有对读取和写一个waveform记录的支持。类似在devAsynInt32设备支持中aiRecord,支持SCAN “I/O Intr”。

10) asynXXXTimeSeries设备支持(XXX=Int32, Int64或Float64)

以下支持可用:

device(waveform,INST_IO,asynInt32TimeSeries,"asynInt32TimeSeries")
device(waveform,INST_IO,asynInt64TimeSeries,"asynInt64TimeSeries")
device(waveform,INST_IO,asynFloat64TimeSeries,"asynFloat64TimeSeries")

devAsynXXXTimeSeries.c提供EPICS设备支持来采集值的一个时序放入一个waveform记录。它对实现了在asynInt32, asynInt64或asynFloat64接口上回调的驱动程序有效。这允许比使用记录支持和数据库操作能够得到的更快和高效的从一个驱动程序的值采集。waveform记录RARM字段用于控制采集,如下:

  • RARM=1:擦除并且启动采集,即:清除这个waveform记录为0,设置NORD=0, BUSY=1并且启用回调。
  • RARM=2:停止采集,设置BUSY=0.
  • RARM=3:在不清除这个waveform或者设置NORD=0地启动采集(设置BUSY=1)

11) asynUInt32Digital设备支持

以下支持可用:

device(bi,INST_IO,asynBiUInt32Digital,"asynUInt32Digital")
device(bo,INST_IO,asynBoUInt32Digital,"asynUInt32Digital")
device(longin,INST_IO,asynLiUInt32Digital,"asynUInt32Digital")
device(longout,INST_IO,asynLoUInt32Digital,"asynUInt32Digital")
device(mbbi,INST_IO,asynMbbiUInt32Digital,"asynUInt32Digital")
device(mbbo,INST_IO,asynMbboUInt32Digital,"asynUInt32Digital")
device(mbbiDirect,INST_IO,asynMbbiDirectUInt32Digital,"asynUInt32Digital")
device(mbboDirect,INST_IO,asynMbboDirectUInt32Digital,"asynUInt32Digital")

devAsynUInt32Digital.c为实现了接口asynUInt32Digital的驱动程序提供了EPICS设备支持。INP或OUT字段必需定义asynMask。在传给asynMask中指定的掩码在对asynUInt32Digital方法的调用中被使用。另外,它用于设置bi和bo记录中掩码字段以及在mbbi, mbbo, mbbiDirect和mbboDirect记录中掩码和shft字段。

1) biRecord

一个值被传给了rval。asynInt32-支持SCAN "I/O Ingtr"。如果这个记录是被"I/O Intr"扫描的,则当registerInterruptUser回调被调用时,它保存这个值并且调用scanIoRequest。当这个记录被运行时,这个保存值被放入了rval。如果这个记录不是"I/O Intr"被扫描的,每次运行这个记录时,通过对pasynUInt32Digital->read的调用,读取一个新值。

2) boRecord

rval被写。

3) longinRecord

一个值被传递给val。在每次运行这个记录时,读取一个新值。类似aiRecord,支持SCAN “I/O Intr”。

4) longoutRecord

val被写。

5) mbbiRecord

一个值被传给rval。每次运行这个记录时,读取一个新值。类似aiRecord,支持SCAN "I/O Intr"。

6) mbboRecord

rval被写。

7) mbbiDirectRecord

一个值被传递给rval。每次运行这个记录时,读取一个新值。类似aiRecord,支持SCAN "I/O Intr"。

8) mbboDirectRecord

rval被写。

二进制输入示例记录

record(bi,"biUInt32Bit0") {
    field(SCAN,"I/O Intr")
    field(DTYP,"asynUInt32Digital")
    field(INP,"@asynMask( $(port) , 0, 0x1 , 1.0) ")
    field(ZNAM,"zero")
    field(ONAM,"one")
}

二进制输出示例记录

record(bo,"boUInt32Bit2") {
    field(DTYP,"asynUInt32Digital")
    field(OUT,"@asynMask( $(port) , 0, 0x4 , 1.0) ")
    field(ZNAM,"zero")
    field(ONAM,"one")
}

长整数输入示例记录

record(longin,"liUInt32") {
    field(SCAN,"I/O Intr")
    field(DTYP,"asynUInt32Digital")
    field(INP,"@asynMask( $(port) , 0, 0xffffffff , 1.0) ")
}

长整数输出示例记录

record(longout,"loUInt32") {
    field(DTYP,"asynUInt32Digital")
    field(OUT,"@asynMask( $(port) , 0, 0xffffffff , 1.0) ")
}

多位输入示例记录

record(mbbi,"mbbiUInt32") {
    field(SCAN,"I/O Intr")
    field(DTYP,"asynUInt32Digital")
    field(INP,"@asynMask( digital , 0, 0x3 , 1.0) ")
    field(ZRST,"zero")
    field(ONST,"one")
    field(TWST,"two")
    field(THST,"three")
    field(ZRVL,"0x0")
    field(ONVL,"0x1")
    field(TWVL,"0x2")
    field(THVL,"0x3")
}

多位输出示例记录

record(mbbo,"mbboUInt32") {
    field(DTYP,"asynUInt32Digital")
    field(OUT,"@asynMask( digital , 0, 0x7 , 1.0) ")
    field(ZRST,"zero")
    field(ONST,"one")
    field(TWST,"two")
    field(THST,"three")
    field(FRST,"four")
    field(FVST,"five")
    field(SXST,"six")
    field(SVST,"seven")
    field(ZRVL,"0x0")
    field(ONVL,"0x1")
    field(TWVL,"0x2")
    field(THVL,"0x3")
    field(FRVL,"0x4")
    field(FVVL,"0x5")
    field(SXVL,"0x6")
    field(SVVL,"0x7")
}

12) asynFloat64设备支持

以下支持可用:

device(ai,INST_IO,asynAiFloat64,"asynFloat64")
device(ai,INST_IO,asynAiFloat64Average,"asynFloat64Average")
device(ao,INST_IO,asynAoFloat64,"asynFloat64")

devAsynFloat.c提供了对实现了接口asynFloat64的驱动程序的EPICS设备支持。

1) aiRecord

一个值被传给了val。从R4-33开始,支持。通过ASLO/AOFF记录字段进行缩放,以及通过SMOO字段进行平滑。

  • asynFloat64:支持SCAN "I/O Intr"。如果这个记录是"I/O Intr"扫描的,则当registerInteruptUser回调被调用时,它保存这个值并且调用scanIoReqest。当这个记录被运行时,这个被保存的值被放入了val。如果这个记录不是"I/O Intr"扫描的,则在每次运行这个记录时,通过对pasynFloat64->read的调用,读取一个新值。
  • asynFloat64Average:registerInterruptUser回调把这个新值加入一个和中并且也增加了采样数目。当这个记录被运行时,计算这个平均并且这个和和采样数目被置为0。如果在新数据到达前(numAverage==0),这个记录被运行了,这个记录被设置成UDF/INVALID,UDF被设置成TRUE,并且这个值被保留不变。可以周期地或用SCAN=I/O Intr扫描这个记录。如果这个记录设为SCAN=I/O Intr,每次NumAverage回调读取已经到达时,则计算这个平均值并且运行这个记录。在ai记录中的SVAL字段被用于设置NumAverage。

2) aoRecord

val字段被写。从R4-33开始,支持通过ASLO/AOFF记录字段进行缩放。

13) asynFloatXXXArray设备支持(XXX=32或64)

以下支持可用:

device(waveform,INST_IO,asynFloatXXXArrayWfIn,"asynFloatXXXArrayIn")
device(waveform,INST_IO,asynFloatXXXArrayWfOut,"asynFloatXXXArrayOut")

devAsynFloatXXXArray.c为实现了接口asynFloatXXXArray的驱动程序提供EPICS设备支持。它有对读取和写一个waveform记录的支持。类似在devAsynInt32设备支持中aiRecord,支持SCAN “I/O Intr”。

14) asynOctet设备支持

device(stringin,INST_IO,asynSiOctetCmdResponse,"asynOctetCmdResponse")
device(stringin,INST_IO,asynSiOctetWriteRead,"asynOctetWriteRead")
device(stringin,INST_IO,asynSiOctetRead,"asynOctetRead")
device(stringout,INST_IO,asynSoOctetWrite,"asynOctetWrite")
device(waveform,INST_IO,asynWfOctetCmdResponse,"asynOctetCmdResponse")
device(waveform,INST_IO,asynWfOctetWriteRead,"asynOctetWriteRead")
device(waveform,INST_IO,asynWfOctetRead,"asynOctetRead")
device(waveform,INST_IO,asynWfOctetWrite,"asynOctetWrite")
device(waveform,INST_IO,asynWfOctetWriteBinary,"asynOctetWriteBinary")

对实现了asynOctet接口的驱动程序的支持。这个支持是用于stringin/stringout和waveform记录。waveform支持类似于string支持。waveform记录必须定义FTVL为CHAR或UCHAR,即:它必须是一个octets的数组。waveform提供了string支持没有提供的以下特性:

  • 无限尺寸--sting记录最大仅保存40个字符。
  • string和二进制数据。从R4-30开始,asynWfWriteOctet调用strlen()来确定这个字符串的长度,并且传递这个长度给驱动程序,即:不包含末尾的nil。这与用于stringout记录的devAsynOctet的行为一致。在R4-30中添加的asynOctetWriteBinary支持总是使用NORD作为其传递给这个驱动程序的长度,并且不调用strlen()。

提供了四种支持类型:

1) CmdResponse:INP字段是这样的格式

 field(INP,"@asyn(portName,addr,timeout) cmd")

在记录初始过程中,cmd被dbTranslateEscape转换。产生的字符串是要发送给设备的命令。当这个记录运行时,命令被发送给设备并且响应读入到这个记录。

2) WriteRead:INP字段时这样的格式:

field(INP,"@asyn(portName,addr,timeout) pvname")

pvname必须指向在相同IOC中一个记录中一个字段。在记录初始化过程中,定位这个pvname。当这个记录被运行时,dbGet被调用来读取pvname的当前值。这个值被发送给设备。接着发送一个读取并且结果被存储在这个记录中。对于asynSiOctetWriteRead,从pvname获取的值在发送它前经常dbTranslateEscaple。对于asynWfOctetWriteRead,不通过dbTranslateEscaple传递它。

3) Write INP(OUT)字段是这种格式:

field(INP,"@asyn(portName,addr,timeout) drvUser")

如果portDriver实现了接口asynDrvUser,drvUser是被传递给这个portDriver的信息。当这个记录被运行,存储在这个记录中的值被发送给设备。

4) Read INP字段是这种格式:

field(INP,"@asyn(portName,addr,timeout) drvUser")

如果portDriver实现了接口asynDrvUser,drvUser是被传递给这个portDriver的信息。当这个记录被运行时,进行一次读取请求。结果被读入这个记录。

15) 记录警报

通用的EPICS设备支持在错误发生时设置记录警报状态和严重性。从R4-30开始,alarmStaus和alarmSeverity字段被添加到了asynUser结构体。驱动程序能够使用这些字段显式地控制记录STAT和SEVERITY字段,独立于返回返回状态或者asynUser.auxStatus字段。

如果pasynUser->alaramStatus或者pasynUser->alarmSeverity字段是0,则记录警报状态和严重性受控于函数返回状态或者asynUser.auxStatus字段。对于不适用回调(不是SCAN=I/O Intr或asynXXXAverage或asynXXXTimeSeries)的记录,状态信息在接口函数调用(例如:pasynInt32->read())的asynStatus返回中被从驱动程序传递到了设备支持。驱动程序使用函数pasynEpicsUtils->asynUserToEpicsAlarm()映射asynStatus值到记录STAT和SEVR值。SEVR字段当前中总是为任何错误被设置为INVALID_ALARM。使用以下设置STAT字段:

  asynSuccess = epicsAlarmNone
  asynTimeout = epicsAlarmTimeout
  asynOverflow = epicsAlarmHWLimit
  asynError = epicsAlarmRead or epicsAlarmWrite
  asynDisconnected = epicsAlarmComm
  asynDisabled = epicsAlarmDisable

对于使用回调的记录,使用在回调中被传递的pasynUser中pasynUser->auxStatus字段从驱动程序传递状态信息给设备支持。在asyn R4-19中添加了这个特性。在那个发行版前,驱动程序控制使用回调的记录的警报状态是不可能的。驱动程序应该为正常操作设置pasynUser->auxStatus为asynSuccess而为另一个值来表示一个问题。以上描述的相同映射用于控制STAT和SEVR的值。如果pasynUser->alarmStatus或pasynUser->alarmSeverity字段是非零,则这些值用于设置记录STAT和SEVR字段,不论asynUser.auxStatus的值。

猜你喜欢

转载自blog.csdn.net/yuyuyuliang00/article/details/127913397