EPICS StreamDevice模块 -- 4

五、记录运行

1、正常运行

StreamDevice是一个异步设备支持。当这个记录被运行时,调度这个协议启动并且这个记录留为有效(PACT=1)。协议自身运行在另一个线程中。那意味着在这个协议中任何等待不会推迟这个IOC的任何其它部分。

在这个协议结束后,记录被再次运行,这个留PACT=0,触发monitors并且允许这个转发链接FLNK。注意:指向一个StreamDevice记录的带有PP标记的输入链接将首先读取这个旧值并且之后启动这个协议。这是一个所有异步EPICS设备支持都有的问题。

在这个协议中第一个out命令为独占访问锁定这个设备。那表示其它记录不能与那个设备进行通信。这确保了由设备给出的应答到达发送这个请求的记录。在一个很多设备在不同地址的总线上,这通常只锁定一个设备。当协议结束时,解锁设备。尝试锁定相同设备的另一个记录必须等待并且获取一个LockTimeout。

如果发生了任何错误,协议被取消。记录将有设置其SEVR字段为INVALID并且STAT字段为描述这个错误的某个东西:

1) TIMEOUT:因为其它记录保持这个设备忙或者设备没有及时响应(ReplyTimeout)。

2) WRITE:输出没有及时被写到设备(WriteTimeout)。

3) READ:来自设备的输入启动了但意外终止了(ReadTimeout)。

4) COMM:设备驱动程序报告设备断开了。

5) CALC:输入不匹配in命令的参数字符串或者它包含了这个记录不接受的值。

6) UDF:某个致命错误发生了或者记录还未被正确地初始化(例如:因为这个协议是错误地)。

如果协议被取消,如果定义了一个异常handler,会执行它。即使这个异常handler能够没有进一步错误地完成,协议将不继续,并且将根据原先地错误相应地设置SEVR和STAT。

2、初始化

在启动IOC后从硬件初始化记录,尤其输出记录,是有用的。出于这个目的,通常以一个异常处理初始化。在任何扫描任务开始前在iocInit阶段@init handler作为initRecord()函数的组成部分被调用并且之后在以下列出的环境可能被再次运行。

对比于正常运行,协议被同步地处理。那表示在@init handler结束前initRecord()不返回。因而,记录一个接一个初始化。扫描任务没有启动并且iocInit在所有@init handler结束前不返回。如果这个handler出错了,记录保持未初始化:UDF=1, SEVER=INVALID, STAT=UDF。

@init handler与PINI字段没有关系。这个handler不允许这个记录也不触发转发链接或者带有PP标记地任何链接。它在PINI被处理前运行。如果这个记录有PINI=YES,在所有记录的@init handlers结束后,PINI运行是一个正常的运行。

取决于记录类型,格式化转换器从正常运行工作略微不同。详细参考可支持的记录类型。

如果@init handler已经读取一个值并且没有错误的完成了,这个记录在已定义的状态开始。那表示UDF=0, SEVR=NO_ALARM, STAT=NO_ALARM,并且VAL字段包含了从设备读取的值。

如果没有按照@init handler,VAL和RVAL保持不变。那表示它们包含在记录定义中定义的,从一个常数INP或DOL字段读取或者从一个重启系统恢复的值。(例如:来自synApps包的autosave)。

在以下情况中调用@init handler:

  • 如以上描述的记录初始化过程中在由iocInit启动时。
  • (在IOC用iocPause被暂停后)在扫描任务重新开始前在用iocRun继续这个IOC时以及在PINI=RUN的记录被运行前。
  • 例如当用streamReload ["recordname"]重载这个协议时。
  • 当StreamDevice探测到设备已经重新连接(在断开连接后)。这包含这种情况在IOC启动时,设备断开了。注意:一些驱动程序仅周期地测试连接,例如:asynIPPort驱动程序每几秒测试它。因而在设备在线和记录重新初始化之间会有一个小延时。
  • 当streamReinit "asynPortname"[,addr]被调用时(如果使用一个asynDriver端口)
  • 当"魔术值"2被写到记录的.PROC字段。在这种情况中,这个记录被运行并且因而其FLNK以及带PP标记的链接被触发。

3、I/O Intr

StreamDevice支持I/O事件扫描。这是一种模式,在此模式中,当设备发送输入时,记录运行被设备触发。

依据协议执行,这表示:当SCAN字段被设置成I/O Intr时(在iocInit过程中或之后),这个协议不允许这个记录地启动。遇到第一个in命令时,协议被暂停。如果设备已经被锁定(即:有一个在协议中更早的out命令),它现在被解锁。那表示其它记录在这个记录正在等待输入时可以与此设备进行通信。这个in命令忽略replyTimeout,它一直等待。

这个协议现在接收来自这个设备的任何输入。它也获取被定向到其它记录的所有输入的副本。不匹配的输入不产生一个失配异常。它仅重启in命令,直到匹配输入被接收。

在接收到匹配输入后,协议正常地继续。所有其它in命令被正常的处理。当这个协议已经结束时,这个记录被运行。它接着触发monitors, forward链接等。在这个记录已经被运行后,这个协议重新开始。

这个模式在两种情况中有用:首先对于在不被请求下自动发送数据的设备有用。第二对于分发在一条消息中多个值到不同记录。在这种情况中,一个记录会向这个设备发送一条请求并且从那个响应中只挑选一个值。其它值被在I/O模式的记录读取。

示例:

设备dev1有一个由一个起始值和一个终止值定义的"感兴趣区域"(ROI)。当请求"ROI?"时,它应答像"ROI 17.3 58.7"的东西,即:一个包含这两个值的字符串。

当我们需要两个ai记录存储这两个值。当记录ROI:start被运行时,它从设备请求ROI。记录ROI:end自动更新。

record (ai "ROI:start") {
    field (DTYP, "stream")
    field (INP,  "@myDev.proto getROIstart dev1")
}
record (ai "ROI:end") {
    field (DTYP, "stream")
    field (INP,  "@myDev.proto getROIend dev1")
    field (SCAN, "I/O Intr")
}

两个协议中仅一个协议发送一个请求,但两个协议读取相同应答消息中它们的部分。

getROIstart {
    out "ROI?";
    in  "ROI %f %*f";
}
getROIend {
    in  "ROI %*f %f";
}

注意:其它值也被每个协议解析,但由于%*格式被跳过。即使getROIend协议可以从其它请求接收输入,它也悄悄地忽略不易以"ROI"开头,后跟两个浮点数值的每条消息。

六、记录类型

支持的记录类型

StreamDevice支持EPICS base中可以有设备支持的所有标准记录类型。

对于每个支持的记录类型有单独一页:

aai aao ai ao bi bo calcout int64in int64out longin longout lsi lso mbbiDirect mbboDirect mbbi mbboscalcout stringin stringout waveform

猜你喜欢

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