二进制输入记录(bi)

这个数据类型通常用于获取一个二进制值0或1。大部分设备支持模块从硬件获取值并且放置这个值到RVAL。对于这些设备,记录processing根据RVAL(0, 非0)设置VAL=(0,1)。设备支持模块可以可选地直接从VAL读取一个值。

提供软设备模块去通过数据库(dbPutField)或通道访问(dbPutLink)链接获取输入。提供了两个软设备支持模块:Soft Channel和Raw Soft Channel。第一个允许VAL是一个任意无符号short整数。第二个就像常规的硬件模块读取值到RVAL。

参数字段

在下面描述了记录专用字段,按功能分组。

扫描参数

二进制输入记录有用于指定在什么情况下将运行这个记录的标准字段。在Scan Fields中描述了这些字段。

读取和转换参数

 读取和转换字段确定二进制输入记录从哪里获取其输入并且如何转换raw信号到工程单位。INP字段包含设备支持从何处获取其值的地址。如果二进制输入记录从硬件获取它的值,必须在INP字段中输入板卡的地址,并且在DTYP字段中必须输入这个设备支持模块的名称。有关硬件地址的格式的信息见Address Specification。

对于指定Soft Channel或Raw Soft Channel设备支持例程的记录,INP字段可以是一个通道或者一个数据库链接,或者一个常数。如果是一个常数,可以通过dbPuts直接更改VAL。有关数据库和通道访问地址格式的信息见Address Specification。有关软设备支持的信息也见本文中"Device Support for Soft Records"。

如果这个记录从硬件获或者使用Raw Soft Channel设备支持获取其值,这些设备支持例程放置值在RVAL字段,接着使用在下一部分中描述的过程转换它。

 转换字段

除非设备支持模块直接读取一个值到VAL或者使用Soft Channel设备支持,否则根据RVAL字段是(0, 非0),设置VAL字段为(0,1)。以在ZNAM或ONAM字段中指定的字符串之一,获取这个值。ZNAM字段有一个对应0状态的字符串,所以当以这个字符串获取这个值,put_enum_str()将返回一个0。ONAM字段保存对应1状态的字符串,所以当以这个字符串获取这个值,put_enum_str()返回一个1。

用于操作显示的参数

这些参数用于向操作者显示有意义数据。get_enum_str()记录支持例程可以获取对应这个VAL的状态的状态字符串。如果这个值是1,get_enum_str()将返回在ONAM字段中的字符串;并且如果0,get_enum_str()将返回ZNAM字符串。

有关这个记录名(NAME)和描述(DESC)字段更多信息见Fields Common to All Record Types。

这些参数用于确定二进制输入记录是否处于警报条件以及确定那个条件的严重性。这个二进制输入的可能的警报条件是SCAN,READ状态警报,以及状态警报的变化。设备支持例程调用SCAN和READ警报 。

用户可以在ZSV和OSV字段中选择每个状态的严重性。用于这些字段的可能警报是NO_ALARM, MINOR和MAJOR。ZSV字段保存了对应0状态的严重性;OSV保存了对应1状态的严重性。当状态在0和1之间变化时,COSV产生一个警报,并且这个严重性被配置成MINOR或MAJOR。

记录警报以及标准字段的完整解释见Alarm Specification。Alarm Fields列出了与所有记录类型共有的警报相关的字段。

运行时参数

这些参数是由运行时代码使用用于运行这个二进制输入记录。它们是使用数据库配置工具不可配置的。

ORAW用于确定在为VAL触发monitors的同时是否为RVAL触发monitors。

由设备支持例程给MASK赋一个值。这个值用于操作这个记录的值,但仅是硬件设备支持例程关注的。

LALM字段保存上次发生状态警报变化发生的值。它用于实现状态警报的变化,并且仅在COSV是MAJOR或MINOR时才有意义。

MSLT字段由process()记录支持例程使用来去顶是否调用archive和值变化monitors。如果MSLT不等于VAL,调用它们。

仿真模式参数

以下字段用于在仿真模式操作这个记录。

如果SIMM(通过SIML获取)是YES或RAW,记录被置入SIMS严重性并且通过SIOL获取这个值(缓存在SVAL中)。如果SIMM是YES,SVAL不经转换地被写入VAL,如果SIMM是RAW,SVAL被放入RVAL并且被转换。SSCN设置在仿真模式中要用的一个不同SCAN机制。SDLY设置一个用于异步仿真运行的延时(秒)。

记录支持例程

记录支持例程

1)

long init_record(struct dbCommon * precord, int pass)

 如果SIML类型是一个常数链接,这个例程用SIML的值初始化SIMM或者如果SIML类型是PV_LINK,创建一个通道访问链接。根据SIOL是一个CONSTANT或PV_LINK,对SVAL进行类似地初始化。

这个例程接着检查设备支持是否可用以及一个设备支持例程是否存在。如果都不存在,发出一条错误消息,并且终止正在运行的process。

如果设备支持包含init_record(),调用它。

2) 

long process(struct dbCommon * precord)

见以下"Record Processing"。

3)

long get_enum_str(const struct dbAddr * paddr, char * pbuffer);

 获取对应VAL的ASCII字符串。

4) 

long get_enum_strs(const struct dbAddr * paddr, struct dbr_enumStrs * p);

获取对应ZNAM和ONAM的ASCII串。

5) 

long put_enum_str(const struct dbAddr * paddr, const char * pbuffer);

检查字符串是否匹配ZNAM或ONAM,并且如果匹配,设置VAL。

记录运行

记录运行实现以下算法:

1) 检查合适的设备支持模块是否存在。如果它不存在,发出一条错误消息并且以PACT字段仍然设为TRUE,结束正在运行的process。这确保不再为这个记录调用processes。因而不会发生错误风暴。

2) 调用readValue()。详细见"Input Records"。

3) 如果PACT已经被更改为TRUE,设备支持读取例程已经启动但未完成读取一个新输入值。在这种情况中,正在运行的process例程仅返回,保留PACT为TRUE。

4) 转换。

  • status=read_bi
  • PACT=TRUE
  • 调用recGblGetTimeStamp()
  • 如果status是0,根据RVAL是(0,非0),设置VAL=(0,1)并且UDF=False。
  • 如果status是2,设置status=0。

5) 检查警报:这个例程检查新的VAL是否引起警报状态和严重性发生变化。如果是,NSEV,NSTA和LALM被设置。注意:如果VAL大于1,不执行检查。

6) 检查是否应该调用monitors:

  • 如果警报状态或严重性发生变化,调用警报monitors。
  • 如果MSLT不等于VAL,调用archive和值变化monitors。
  • 当其它monitors被调用时,检查用于RVAL的monitors。
  • 重置NSEV和NSTA为0。

7) 如果需要,扫描forward链接,设置PACT为FALSE,并且返回。

设备支持

设备支持相关字段

每个二进制输入记录必须有一个相关联的设备支持例程集合。设备支持例程的主要作用时在调用read_bi()时去获取一个新的raw输入值。设备支持主要相关字段如下:

设备支持由以下例程组成:

1) 

long report(int level);

 这个可选的例程是被IOC命令dbior调用,并且被传递用户请求i的报告级别。它应该打印一条有关设备支持的状态的报告到stdout。level参数可能用于以更高级别输出更详细地信息,或者选择有不同级别地不同信息类型。级别0应该打印不多于一小段概要。

2)

long init(int after);

这个可选例程在IOC初始化时被调用两次。第一次调用用整数参数after设置为0发生在进行任何init_record()调用前。第二次调用用after设置为1发生在已经进行所有init_record()调用之后。

3) 

long init_record(struct dbCommon * precord);

这个例程是可选的。如果提供了,由记录支持init_record()例程调用它。

4)

long get_ioint_info(int cmd, struct dbCommon * precord, IOSCANPVT * ppvt);

每次这个记录被添加到一个I/O事件扫描列表或者被从一个I/O事件扫描列表删除时,由ioEventScan系统调用这个例程。根据这个记录被添加到I/O事件列表或者被从I/O事件列表删除,cmd有值(0,1)。必须为能够使用ioEvent Scanner的任何设备类型提供它。

5) 

long read_bi(struct dbCommon * precord);

这个例程必须提供一个新输入值。它返回以下值:

0:成功。一个新raw值被放入RVAL。记录支持模块根据RVAL是(0,非0),设置VAL为(0,1)。

2:成功,但不转换。

其它:错误。

用于软记录的设备支持

两个软设备支持模块,为不于实际硬件设备相关联的输入记录提供了Soft Channel和Raw Soft Channel。INP链接类型必须是CONSTANT,DB_LINK或CA_LINK。

Soft Channel

如果INP链接类型是CONSTANT,则这个常量值被init_record()存储在了VAL,并且UDF被设置成FALSE。通过dbPut()请求能够更改VAL。如果INP链接类型是PV_LINK,由init_record()调用dbCaAddInlink()。

read_bi()调用dbGetLinkValue去读取VAL的当前值。

如果dbGetLinkValue()的状态是0,则read_bi()设置UDF为FALSE。返回dbGetLinkValue()的状态。

Raw Soft Channel

这个模块除了值被读取到RVAL外,类似先前的模块。

read_bi()返回一个0值。因而这个记录正在运行的process例程将强制VAL为0或1。

为了区分Soft Channel和Raw Soft Channel的区别,我设计了以下一个数据库文件:

# 使用设备驱动Soft Channel,这个记录的INP通过数据库访问获取longin记录的VAL值
record(bi, "$(USER):biSoft")
{
        field(SCAN, "Passive")
        field(INP,  "$(USER):longin")
        field(ZNAM, "Close")
        field(ONAM, "Open")
        field(DTYP, "Soft Channel")
        field(FLNK, "$(USER):biRawSoft.PROC")
}

# 使用设备驱动Raw Soft Channel,这个记录的INP通过数据库访问获取longin记录的VAL值
record(bi, "$(USER):biRawSoft")
{
        field(SCAN, "Passive")
        field(INP,  "$(USER):longin")
        field(ZNAM, "Close")
        field(ONAM, "Open")
        field(DTYP, "Raw Soft Channel")

}
# 用户可以通过通道访问设置这个longin记录实例的VAL值
# 这个VAL值作为biSoft和biRawSoft记录的输入
record(longin, "$(USER):longin")
{
        field(SCAN,"Passive")
        field(INP, "0")
        field(DTYP, "Soft Channel")
        field(FLNK, "$(USER):biSoft.PROC")
        field(PINI,"YES")
}

把以上数据库文件加载到IOC中,使用通道访问命令行工具对其进行测试:

# 初始时,longin记录实例的值为0,biSoft和biRawSoft记录的值为Close
[blctrl@bjAli dev]$ caget blctrl:longin
blctrl:longin                  0
[blctrl@bjAli dev]$ caget blctrl:biSoft
blctrl:biSoft                  Close
[blctrl@bjAli dev]$ caget blctrl:biRawSoft
blctrl:biRawSoft               Close

# 通过通道访问向longin记录的VAl字段写入1,由于这个记录是被动的,所以其开始运行
# 这三个记录运行结束,发现biSoft和biRawSoft记录的值变成了Open
[blctrl@bjAli dev]$ caput blctrl:longin 1
Old : blctrl:longin                  0
New : blctrl:longin                  1
[blctrl@bjAli dev]$ caget blctrl:biSoft
blctrl:biSoft                  Open
[blctrl@bjAli dev]$ caget blctrl:biRawSoft
blctrl:biRawSoft               Open

# 通过通道访问向longin记录的VAl字段写入2,由于这个记录是被动的,所以其开始运行
# 这三个记录运行结束,发现biSoft记录的值变成非法之,而biRawSoft记录的值还是Open
# 说明使用Soft Channel的记录接收的合法值只有0和1,而使用Raw Soft Channel的记录接收0时设置
# VAL为0,其它情况设置VAL为1
[blctrl@bjAli dev]$ caput blctrl:longin 2
Old : blctrl:longin                  1
New : blctrl:longin                  2
[blctrl@bjAli dev]$ caget blctrl:biSoft
blctrl:biSoft                  Illegal_Value
[blctrl@bjAli dev]$ caget blctrl:biRawSoft
blctrl:biRawSoft               Open

猜你喜欢

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