这个select记录根据获最多获取自12个位置的输入计算一个值。选择算法可以是以下之一:Specified, High Signal, Low Signal, Median Signal。每个输入可以是一个常数,数据库链接或者一个通道访问链接。
用于扫描的参数
select记录有用于指定在什么情况下将运行这个记录的标准字段。这些字段在Scan Fields中被列出。
用于读取的参数
INPA-L链接确定了这个select记录要从哪里获取其值或者计算其最终值。INPA-L链接是由用户配置的输入链接,可以是常数,通道访问链接或者数据库链接。如果通道访问或数据库链接,获取对应每个链接的一个值并且被放入相应的值字段A-L。如果任何输入是一个常数,对应那个链接的值字段将被初始化为赋给那个链接的常数值并且可以通过dbPuts被修改。
任何没有被定义的链接被这个select记录和其算法忽略。一个未被定义的链接是其值是0的任意常数链接。在初始化时,对应这样字段的相应值链接被设置为NaN,其表示MISSING。为了定义链接和其字段,一个未被定义的链接的值字段在运行时可以被从NaN更改为另一个值。注意:所有未被定义的链接必须被识别,使得选择算法按预计运行。
用于选择的参数
选择算法是由用户可配置的三个字段决定的:选择机制(SELM)字段,选择编号(SELN)字段以及索引值位置(NVL)字段。
SELM字段有四个选项,即,如下的四种算法:
对于每种算法,selection记录的VAL字段被不同都确定。对于Specified,VAL字段被设置成由SELN字段指定的值字段(A,B,C,D,E,F,G,H,I,J,K或L)。SELN字段包含一个从0-11的值,其对应要被使用的值字段(0表示使用;1表示使用B等)。如何配置NVL字段则确定了SELN的值。NVL是一个输入链接,从其可以为SELN获取一个值。像大多数其它输入链接,NVL可以是一个常数,或者通道访问或者数据库链接。如果NVL是一个链接,从NVL中位置获取SELN。如果一个常数,SELN被初始化为赋给这个常数的值并且可以通道dbPuts被更改。
High Signal, Low Signal和Median Signal算法不使用SELN或NVL。如果选择了High Signal,VAL被设置为所有已定义值字段(A-L)的最大值。如果选择了Low Signal,VAL被设置为所有已定义值字段(A-L)的最小值。如果选择了Median Signal,VAL被设置成已定义值字段(A-L)的中位数。(注意:这些算法从值字段选取;它们不从值字段索引选取。例如,除非A字段的值自身是所有已定义值得最小值,否则Low Signal将不选取A字段的值。)
用于操作显示的参数
这些参数用于向操作者显示有意义的数据。它们以文本或者图形显示select记录的值和其它参数。
EGU是一个最多16个字符的字符串,描述这个selection记录操作的单位。由get_units记录支持例程获取它。
HOPR和LOPR字段为VAL,HIHI,HIGH,LOW和LOLO字段设置上下显示限制。get_graphic_double和get_control_double记录支持例程获取这些字段。PREC字段确定用于显示VAL的浮点精度。在调用get_precision记录支持例程时,使用它。
有关记录名(NAME)和描述(DESC)字段的更多信息见Fields Common to All Record Types。
用于警报的参数
对于select记录的可能警报条件是SCAN, READ和limit警报。SCAN和READ警报被记录或者设备支持例程调用。限制的警报是由用户使用数值在HIHI,LOLO,HIGH和LOW字段中配置的。它们为VAL字段指定条件。对于这些字段中每一个字段,有一个相应的严重性字段,它可以是NO_ALARM, MINOR或MAJOR。Alarm Fields列出了与所有记录类型共有的警报相关的字段。
用于监控的参数
这些字段是由用户配置的。它们用作用于VAL字段的archiver和monitor调用的死区。除非VAL变化多于每个指定的值,否则将不调用各自的monitors。如果这些字段有一个0值,每次VAL变化时,monitors被触发;如果它们有一个-1值,这个记录每次运行时,触发monitors。
运行时参数
这些参数是由运行时代码使用用于运行这个selection记录。它们在运行前是不可配置的,在运行时也不可修改的。它们表示这个记录的当前值。记录支持例程为了更加高i奥运行使用它们中的一些。
VAL字段是selection记录运行的结果。其它记录用正常方式或者通过数据库访问能够访问它,但除了被这个记录自身外,它是不可修改的。LALM,ALST和MLST被用于各自实现对警报、archiver和monitors的HYST,ADEL和MDEL回滞因子。
LA-LL字段用于为每个值A-L字段实现monitors。它们表示先前的输入值。例如,除非LA不等于A,否则不调用A的monitors。
记录支持例程
1) init_record
long (*init_record)(struct dbCommon *precord, int pass)
如果NVL是一个常数,SELN被设置成它的值。如果NVL是一个PV_LINK,创建一个通道访问链接。对于每个常数输入链接,用这个常数值初始化相应的值字段(或者如果这个常数有一个0值,则NaN)。
对于每个类型PV_LINK的输入链接,一个数据库或通道访问链接被创建。
2) process
long (*process)(struct dbCommon *precord)
3) get_units 获取EGU
long (*get_units)(struct dbAddr *paddr, char *units)
4) get_graphic_double
long (*get_graphic_double)(struct dbAddr *paddr, struct dbr_grDouble *p)
为一个字段设置上显示和下显示限制。如果这个字段是VAL,HIHI,HIGH,LOW或LOLO,这些限制被设置成HOPR和LOPR,否则如果这些字段有已定义的上和下限制,将使用它们,否则将使用对应这个字段类型的上和下最值。
5) get_control_double
long (*get_control_double)(struct dbAddr *paddr, struct dbr_ctrlDouble *p)
为一个字段设置上控制和下控制限制。如果这个字段是VAL,HIHI,HIGH,LOW或LOLO,这些限制被设置成HOPR和LOPR,否则如果这个字段有已经定义的上和下限制,将使用它们,否则将使用对应这个字段类型的上和下最值。
6) get_alarm_double
long (*get_alarm_double)(struct dbAddr *paddr, struct dbr_alDouble *p)
设置以下值:
upper_alarm_limit = HIHI
upper_warning_limit = HIGH
lower_warning_limit = LOW
lower_alarm_limit = LOLO
记录运行
记录运行实现以下算法:
1) 如果NVL是一个数据库或者通道访问链接,SELN从NVL获取值。如果获取数据库或者通道访问链接的所有值。如果SELM是SELECTED,则仅获取被选取的链接。
2) 实现合适的选择算法。对于SELECT_HIGH, SELECT_LOW和SELECT_MEDIAN,如果输入链接未被定义,忽略输入字段。如果成功,UDF被设置成FALSE。
3) 检查警报。这个例程检查新的VAL是否引起警报状态和严重性变化。如果这样,设置NSTA,NSEV和LALM。它也遵守警报回滞因子(HYST)。因而在警报状态和严重性被降低前,值变化必须多于HYST。
4) 检查是否调用monitors。
- 如果警报状态或严重性已经变化,调用警报monitors。
- 如果满足了ADEL和MDEL条件,调用archive和值变化monitors。
- 如果其它monitors被调用了,检查对应A-L的monitors。
- 重置NSEV和NSTA为0。
5) 如果需要,扫描forward链接,设置PACT为FALSE并且返回。
数据库实例:
这个数据库实例文件一共由7个记录实例组成:
1) $(USER):Int100, $(USER):Int101,$(USER):Int102和$(USER):Int103记录的类型都是longin,它们的VAL字段初始时都分别被设置成了100,101,102和103,用作为$(USER):Sel记录实例提供输入数据源。
2) $(USER):Choose记录实例类型是longin,它是一个被动记录,通过通道访问向其VAL字段写入整数值,并且在其运行结束时,使得$(USER):event记录运行。
3) $(USER):event记录实例类型是event,初始化时,其VAL字段被初始化为1,当其运行时,会使得扫描类型为Event并且其EVNT字段值1为的记录运行。
4) $(USER):Sel记录类型是sel,初始化时,SELM为"Specified", NVL从$(USER):Choose记录读取,输入链接INPA,INPB, INPK和INPL分别指向 $(USER):Int100, $(USER):Int101,$(USER):Int102和$(USER):Int103记录。
record(longin, "$(USER):Int100")
{
field(SCAN, "Passive")
field(INP, "100")
field(DTYP, "Soft Channel")
}
record(longin, "$(USER):Int101")
{
field(SCAN, "Passive")
field(INP, "101")
field(DTYP, "Soft Channel")
}
record(longin, "$(USER):Int102")
{
field(SCAN, "Passive")
field(INP, "102")
field(DTYP, "Soft Channel")
}
record(longin, "$(USER):Int103")
{
field(SCAN, "Passive")
field(INP, "103")
field(DTYP, "Soft Channel")
}
record(longin, "$(USER):Choose")
{
field(SCAN, "Passive")
field(DTYP, "Soft Channel")
field(INP, "0")
field(PINI, "YES")
field(FLNK, "$(USER):Event.PROC")
}
record(event, "$(USER):Event")
{
field(INP, "1")
field(SCAN, "Passive")
field(DTYP, "Soft Channel")
}
record(sel, "$(USER):Sel")
{
field(INPA, "$(USER):Int100")
field(INPB, "$(USER):Int101")
field(INPK, "$(USER):Int102")
field(INPL, "$(USER):Int103")
field(SCAN, "Event")
field(EVNT, "1")
field(NVL, "$(USER):Choose")
field(SELM, "Specified")
}
把以上数据库记录实例文件加载到IOC中,进行记录查看:
epics> dbl
blctrl:Event
blctrl:Int100
blctrl:Int101
blctrl:Int102
blctrl:Int103
blctrl:Choose
blctrl:Sel
另开一个终端,用caget,caput通道访问命令进行测试:
# 查看四个作为数据源的记录的值:
[root@bjAli ~]# caget blctrl:Int100 blctrl:Int101 blctrl:Int102 blctrl:Int103
blctrl:Int100 100
blctrl:Int101 101
blctrl:Int102 102
blctrl:Int103 103
# 查看blctrl:Sel 初始值
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 0
# 向blctrl:Choose写0后,blctrl:Sel通过INPA从blctrl:Int100记录读取数据
[root@bjAli ~]# caput blctrl:Choose 0
Old : blctrl:Choose 0
New : blctrl:Choose 0
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 100
# 向blctrl:Choose写1后,blctrl:Sel通过INPB从blctrl:Int101记录读取数据
[root@bjAli ~]# caput blctrl:Choose 1
Old : blctrl:Choose 0
New : blctrl:Choose 1
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 101
# 向blctrl:Choose写11后,blctrl:Sel通过INPK从blctrl:Int101记录读取数据
[root@bjAli ~]# caput blctrl:Choose 11
Old : blctrl:Choose 1
New : blctrl:Choose 11
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 103
# 向blctrl:Choose写10后,blctrl:Sel通过INPK从blctrl:Int102记录读取数据
[root@bjAli ~]# caput blctrl:Choose 10
Old : blctrl:Choose 11
New : blctrl:Choose 10
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 102
# 更改blctrl:SELM值未"High Signal",更改了选取算法,从已经定义的链接中获取最大值
Old : blctrl:Sel.SELM Specified
New : blctrl:Sel.SELM High Signal
Old : blctrl:Choose 10
New : blctrl:Choose 5
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 103
# 更改blctrl:SELM值未"Low Signal",更改了选取算法,从已经定义的链接中获取最小值
[root@bjAli ~]# caput blctrl:Sel.SELM "Low Signal"
Old : blctrl:Sel.SELM High Signal
New : blctrl:Sel.SELM Low Signal
# 现在向blctrl:choose中写值,作用只是使得以下记录blctrl:Event和blctrl:Sel能够运行
[root@bjAli ~]# caput blctrl:Choose 6
Old : blctrl:Choose 5
New : blctrl:Choose 6
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 100
# 更改blctrl:SELM值未"Median Signal",更改了选取算法,从已经定义的链接中获取中位值
[root@bjAli ~]# caput blctrl:Sel.SELM "Median Signal"
Old : blctrl:Sel.SELM Low Signal
New : blctrl:Sel.SELM Median Signal
[root@bjAli ~]# caput blctrl:Choose 7
Old : blctrl:Choose 6
New : blctrl:Choose 7
[root@bjAli ~]# caget blctrl:Sel
blctrl:Sel 102