数据散出或"dfanout"记录用于最多转发数据到8个其它记录。除了向它添加了转发数据的能力外,它类似于fanout记录。它没有相关联的设备支持。
参数字段
在下面描述记录特定的字段,按功能分组。
扫描参数
数据fanout记录有用于指定其在什么情况下运行的标准字段。在Scan Fields中列出了这些字段。
所需输出参数
数据anout必须指定所需输出值从哪里来,即是:要转发给在其输出链接中的记录的数据。输出模式选择(OMSL)字段决定了输出来自另一个记录或者来自运行时数据库访问。当设为closed_loop时,从在所需输出链接(DOL)字段中指定的链接获取所需输出,DOL字段可以指定一个数据库或者通道访问链接,并且被放置到VAL字段。当设为supervisory时,在运行时所需输出可以通过dbPuts被写入到VAL字段。
DOL字段也可以是一个常数,在这种情况下,VAL字段被初始化为这个常数值。
注意:没有转换参数,因此在其被发送到输出链接前,所需输出值不经过转换。
输出参数
OUTA-OUTH字段指定VAL要被发送到哪里。要转发数据的每个字段必须指定到另一个记录的地址。有关指定链接的信息见Address Specification。
SELL,SELM和SELN字段指定了要使用哪些输出链接。
菜单dfanoutSELM
SELM是一个有三个选项的菜单:
如果SELM是ALL,则使用所有输出链接,并且忽略SELL和SELN的值。
如果SELM是Specified,则SELN的值被用于指定将要使用哪一个链接。如果SELN==0,则不使用链接;如果SELN==1,使用OUTA,并且以此类推。
SELN可以直接设置它的值,或者通过另一个EPICS PV获取它。如果SELL是一个有效的PV链接,则将从链接的PV读取SELN。
如果SELM是Mask,则SELN将被出纳工作一个位掩码。如果SELN的第0位被置1,则OUTA将被写入;如果第1位被设置,OUTB将被写,以此类推。因而,当SELN==5时,OUTC和OUTA都被写入。
操作显示参数
这些参数用于向操作者显示有意义的数据。它们完全不影响这个记录的功能。
- NAME是记录的名称,并且在一个客户端知道这个PV名是对应这个记录的别名时,会是有用的。
- DESC是一个用于简要介绍这个记录的字符串。
- EGU是一个最长16字符的字符串,它命名了VAL字段代表的工程单位。
- HOPR和LOPR字段为VAL,HIHI,LOW和LOLO字段设置了上下显示限制。
- PREC字段确动用于显示VAL和其它DOUBLE字段的浮点精度(即:显示小数点后数字的位数)。
有关记录名(NAME)和描述(DESC)字段的更多信息见Fields Common to All Record Types。
用于警报的参数
记录警报和标准字段的完整解释见Alarm Specifiaction。Alarm Fields列出了与其它所有记录类型都有的警报相关联的其它字段。
用于监控的参数
这些参数用于确定何时发送在VAL字段上的monitors。当值字段超过了上个受监视字段指定的死区时,发送这些monitors,ADEL用于存档monitors而MEDL用于所有其它类型的monitors。如果这些字段有一个0值,在值每次变化时,将触发一个Monitor;如果它们有一个-1值,每次扫描这个记录时,触发monitors。完整解释见"Monitor Specification"。
运行时参数和仿真模式参数
这些参数由运行时代码使用用于运行这个数据扇出记录。它们是不可配置的。它们用于为monitor回调执行回滞因子。
记录支持
记录支持例程
1) init_record()
这个例程初始化被定义的所有输出链接。如果DOL是一个常数或者一个PV_LINK,则它初始化DOL。当初始化输出链接和DOL链接时,如果发生错误,返回一个非0值。
2) process()
见下一部分。
3) get_units()
这个例程复制在EGU字段中指定的字符串到由一个由这个例程传递的指针指定的位置。
4) get_graphic_double()
如果被引用的字段时VAL,HIHI,HIGH,LOW或LOLO,这个例程设置dbr_grDouble结构体的upper_disp_limit成员为HOPR和lower_disp_limit成员为LOPR。
5) get_control_double()
与get_graphic_double()例程相同,除了它使用dbr_ctrlDouble结构体。
6) get_alarm_double ()
当被引用字段是VAL时,设置dbr_alDouble结构体的成员为指定的警报限制:
upper_alarm_limit = HIHI
upper_warning_limit = HIGH
lower_warning_limit = LOW
lower_alarm_limit = LOLO
如果被引用的字段不是VAL,调用recGblGetAlarmDouble()例程。
记录运行
1) process()例程首先检查DOL是否是一个常数链接以及OMSL被设置成“closed_loop”。如果这样,它通过DOL获取一个值并且放置它到VAL。如果没有发生错误,UDF被设置为FALSE。
2) PACT被设置为TRUE,并且设置记录的时间戳。
3) 从SELL获取一个值并且放入SELN。
4) 根据VAL字段内容检查警报范围。
5) 根据SELM的设置和在SELN中的条件,通过为每个链接调用dbPutLink(),通过OUTA-OUTH发送VAL。
6)分别根据MDEL和ADEL的设置,提交VAL字段的值和存档monitors。
7) 运行数据fanout的forward链接。
8) PACT设置FALSE,并且process()例程返回。
示例:
以下是示例数据库文件:
这个数据库文件一共由11个记录实例组成:
1) $(USER):In:Float记录类型是ai,为$(USER):Dfanout记录提供一个输入值。
2) $(USER):Choose记录类型是longin,为$(USER):Dfanout记录的SELN提供一个值,并且$(USER):Dfanout记录在SELM在Specified和Mask模式下,会根据这个值,把VAL字段中的值输出到相应的OUTx指向的记录中。
3) $(USER):Dfanout记录类型是dfanout,根据设定的算法,把其VAL字段输出到OUTx指向的记录。
4) $(USER):Out:Float1-$(USER):Out:Float8记录类型是ai,$(USER):Dfanout记录的OUTA-OUTH按顺序分别指向它们中的一个,用于测试$(USER):Dfanout记录在不同算法下的输出情况。
record(ai, "$(USER):In:Float")
{field(DTYP,"Soft Channel")field(SCAN, "Passive")field(INP, "0")field(FLNK, "$(USER):Dfanout")
}record(longin, "$(USER):Choose")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(dfanout, "$(USER):Dfanout")
{field(DOL, "$(USER):In:Float")field(OMSL, "closed_loop")field(SCAN, "Passive")field(SELM, "All")field(SELL, "$(USER):Choose.VAL")field(OUTA, "$(USER):Out:Float1.VAL")field(OUTB, "$(USER):Out:Float2.VAL")field(OUTC, "$(USER):Out:Float3.VAL")field(OUTD, "$(USER):Out:Float4.VAL")field(OUTE, "$(USER):Out:Float5.VAL")field(OUTF, "$(USER):Out:Float6.VAL")field(OUTG, "$(USER):Out:Float7.VAL")field(OUTH, "$(USER):Out:Float8.VAL")
}record(ai, "$(USER):Out:Float1")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(ai, "$(USER):Out:Float2")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(ai, "$(USER):Out:Float3")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(ai, "$(USER):Out:Float4")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(ai, "$(USER):Out:Float5")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(ai, "$(USER):Out:Float6")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(ai, "$(USER):Out:Float7")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}record(ai, "$(USER):Out:Float8")
{field(DTYP, "Soft Channel")field(SCAN, "Passive")field(INP, "0")
}
测试:
刚加载这个数据库文件后,blctrl:Out:Float1~blctrl:Out:Float8的初始值都为0。
[root@bjAli rec]# caget blctrl:Out:Float1 blctrl:Out:Float2 blctrl:Out:Float3 blctrl:Out:Float4 blctrl:Out:Float5 blctrl:Out:Float6 blctrl:Out:Float7 blctrl:Out:Float8
blctrl:Out:Float1 0
blctrl:Out:Float2 0
blctrl:Out:Float3 0
blctrl:Out:Float4 0
blctrl:Out:Float5 0
blctrl:Out:Float6 0
blctrl:Out:Float7 0
blctrl:Out:Float8 0
1) dfanout记录的SELM字段为All时,当记录运行时,从其DOL获取的值将被发送到其OUTA-OUTH指向的所有记录。
[root@bjAli rec]# caget blctrl:Dfanout.SELM
blctrl:Dfanout.SELM All
[root@bjAli rec]# caput blctrl:In:Float 1.5
Old : blctrl:In:Float 0
New : blctrl:In:Float 1.5
[root@bjAli rec]# caget blctrl:Out:Float1 blctrl:Out:Float2 blctrl:Out:Float3 blctrl:Out:Float4 blctrl:Out:Float5 blctrl:Out:Float6 blctrl:Out:Float7 blctrl:Out:Float8
blctrl:Out:Float1 1.5
blctrl:Out:Float2 1.5
blctrl:Out:Float3 1.5
blctrl:Out:Float4 1.5
blctrl:Out:Float5 1.5
blctrl:Out:Float6 1.5
blctrl:Out:Float7 1.5
blctrl:Out:Float8 1.5
2)当dfanout记录的SELM为Specified时,该记录运行时从DOL获取的值将只被发送到SELN字段中值指定的OUTx指向的记录中(1-8分别对应OUTA-OUTH) 。
[root@bjAli rec]# caput blctrl:Dfanout.SELM "Specified"
Old : blctrl:Dfanout.SELM All
New : blctrl:Dfanout.SELM Specified
[root@bjAli rec]# caput blctrl:Choose 1
Old : blctrl:Choose 0
New : blctrl:Choose 1
[root@bjAli rec]# caput blctrl:In:Float 3.8
Old : blctrl:In:Float 1.5
New : blctrl:In:Float 3.8
[root@bjAli rec]# caget blctrl:Out:Float1 blctrl:Out:Float2 blctrl:Out:Float3 blctrl:Out:Float4 blctrl:Out:Float5 blctrl:Out:Float6 blctrl:Out:Float7 blctrl:Out:Float8
blctrl:Out:Float1 3.8
blctrl:Out:Float2 1.5
blctrl:Out:Float3 1.5
blctrl:Out:Float4 1.5
blctrl:Out:Float5 1.5
blctrl:Out:Float6 1.5
blctrl:Out:Float7 1.5
blctrl:Out:Float8 1.5
[root@bjAli rec]# caput blctrl:Choose 6
Old : blctrl:Choose 1
New : blctrl:Choose 6
[root@bjAli rec]# caput blctrl:In:Float 8.1
Old : blctrl:In:Float 3.8
New : blctrl:In:Float 8.1
[root@bjAli rec]# caget blctrl:Out:Float1 blctrl:Out:Float2 blctrl:Out:Float3 blctrl:Out:Float4 blctrl:Out:Float5 blctrl:Out:Float6 blctrl:Out:Float7 blctrl:Out:Float8
blctrl:Out:Float1 3.8
blctrl:Out:Float2 1.5
blctrl:Out:Float3 1.5
blctrl:Out:Float4 1.5
blctrl:Out:Float5 1.5
blctrl:Out:Float6 8.1
blctrl:Out:Float7 1.5
blctrl:Out:Float8 1.5
3) 当dfanout记录的SELM为Mask时,该记录运行时,会从SELL字段指向的记录获取一个值,此值放入SELN字段,这个值作为选择OUTx输出链接的掩码,低位字节的第0位对应OUTA,以此类推,第7位对应OUTH。
[root@bjAli rec]# caput blctrl:Dfanout.SELM "Mask"
Old : blctrl:Dfanout.SELM Specified
New : blctrl:Dfanout.SELM Mask
[root@bjAli rec]# caput blctrl:Choose 3
Old : blctrl:Choose 6
New : blctrl:Choose 3
[root@bjAli rec]# caput blctrl:In:Float 12.6
Old : blctrl:In:Float 8.1
New : blctrl:In:Float 12.6
[root@bjAli rec]# caget blctrl:Out:Float1 blctrl:Out:Float2 blctrl:Out:Float3 blctrl:Out:Float4 blctrl:Out:Float5 blctrl:Out:Float6 blctrl:Out:Float7 blctrl:Out:Float8
blctrl:Out:Float1 12.6
blctrl:Out:Float2 12.6
blctrl:Out:Float3 1.5
blctrl:Out:Float4 1.5
blctrl:Out:Float5 1.5
blctrl:Out:Float6 8.1
blctrl:Out:Float7 1.5
blctrl:Out:Float8 1.5
[root@bjAli rec]# caput blctrl:Choose 56
Old : blctrl:Choose 3
New : blctrl:Choose 56
[root@bjAli rec]# caput blctrl:In:Float 32
Old : blctrl:In:Float 12.6
New : blctrl:In:Float 32
[root@bjAli rec]# caget blctrl:Out:Float1 blctrl:Out:Float2 blctrl:Out:Float3 blctrl:Out:Float4 blctrl:Out:Float5 blctrl:Out:Float6 blctrl:Out:Float7 blctrl:Out:Float8
blctrl:Out:Float1 12.6
blctrl:Out:Float2 12.6
blctrl:Out:Float3 1.5
blctrl:Out:Float4 32
blctrl:Out:Float5 32
blctrl:Out:Float6 32
blctrl:Out:Float7 1.5
blctrl:Out:Float8 1.5