EPICS通道访问:EPICS网络协议
1)通过网络读写过程变量。
2) 对很多人,CA就是EPICS。
- 尤其如果你的后台是没有IOC数据库的w/系统。
- "集成进EPICS"表示"在网络上与CA会话"。
超过类型的控制系统/IoT协议的优势
1) 对于小型设置"0配置",但放大到大型网络
2) 分布式的,没有中心的"名称服务器"或者"经纪人"瓶颈。
3)读/写/订阅('get', 'put', 'monitor')
- monitor发送初始值。
- 对应确认的结束的'put-callback'选项。
4) 组合了时间戳,单位,状态的数据类型。
5) 在IOCs上的记录提供数据,通道访问提供它们,但不表示你可以列出所有记录
6) IOCs可能变化
7)某些通道由python, LabView等提供,没有记录。
8)来自IOCs和记录的通道访问(以及PV访问)协议不同。
过程变量是什么?
一个带有属性的指定名称数据段。
考虑以下记录,PV是什么:
record(calc, "t1:calcExample")
{
field(DESC, "Sawtooth Ramp")
field(SCAN, "1 second")
field(CALC, "(A<10)?(A+1):0")
field(INPA, "t1:calcExample.VAL")
}
1)"t1:calcExample":
-
PV对应这个记录的当前值。
-
数值0~10,每秒变化。
2)"t1:calcExample.DESC":
- PV对应这个记录的DESC(描述)字段。
- 字符串"Sawtooth Ramp", 静态。
3) "t1:calcExample.VAL":
- 与t1:calcExample相同。
4) “t1:calcExample.SCAN”:
- “1 second”,类型枚举,静态。
5) 一个记录的几乎每个字段可以是一个PV:
- "{record name}.{field name}"。
- 省略字段时,隐含为“.VAL”。
caget, caput, camonitor
1) 'caget'命令行工具,进行读:
> caget t1:calcExample
t1:calcExample 6
> caget t1:calcExample.VAL
t1:calcExample.VAL 9
> caget t1:calcExample.DESC
t1:calcExample.DESC Sawtooth Ramp
2) 'caput'命令行工具,进行写:
> caput t1:calcExample.DESC "Howdy"
Old : t1:calcExample.DESC Sawtooth Ramp
New : t1:calcExample.DESC Howdy
3)'camonitor'命令行工具,监视值变化:
> camonitor t1:calcExample
t1:calcExample 2006-10-06 13:26:03.332756 6
t1:calcExample 2006-10-06 13:26:04.332809 7
t1:calcExample 2006-10-06 13:26:05.332866 8
t1:calcExample 2006-10-06 13:26:06.332928 9
t1:calcExample 2006-10-06 13:26:07.332981 10
t1:calcExample 2006-10-06 13:26:08.333034 0
t1:calcExample 2006-10-06 13:26:09.333097 1
t1:calcExample 2006-10-06 13:26:10.333143 2
… plus one more each second…
… press Ctrl-C to stop …
> camonitor t1:calcExample.DESC
t1:calcExample.DESC 2006-10-06 13:29:12.442257 Howdy
… and then nothing …
客户端如何找到通道
网络知识补充
1) 网络协议(IP)由UDP和TCP组成,以及更底层的ICMP,ARP,...
2)数据报协议(UDP) :
a) 发送网络数据包
- 从一台计算机上的一个端口
- 发送到在一台或多台其它计算机上一个或多个端口
- 在一台目标机上一个或多个监听程序
b) 快!
c) 校验和:如果数据包到达了,正常。
d) 不可靠:数据包丢失,没按顺序到达,多次到达。
3)传送控制协议(TCP)
a) 从一台计算机上一个端口发送一个字节流到另一条计算机上另一个端口,在目标端口上只有一个监听程序。
b) 可靠:字节在接收端按正确顺序到达。基本上,对UDP包添加了序列号,请求重复发送丢失数据包。
b) 较慢,并且消息边界丢失:”Hello Fred“可能会以"Hel"<暂停>"lo F"<暂停>"red!"到达。
搜索和连接过程
搜索请求
1) 一个搜索请求由一个UDP包序列组成
a) 默认:向本地子网广播:在你刚开始时,基本上即插即用。
b) 或者广播给在EPICS_CA_ADD_LIST中列出的IP地址
- 路由器不转发广播
- 你必须添加本地子网外的'其它'子网或者特定IOCs到那个环境变量。
c) 以一个短间隔(0.1s)开始:
- 加倍每次时间,直到到达了5分钟间隔。
- 在它得到了一个响应后停止
- 在"beacon异常"时再次唤醒(之后详细讨论)zhong
2) CA服务器检查每个搜索数据包。
3) 通常在第一个或者前几个数据包时连接。
- 但不存在的PVs引发很多流量
- 尝试清除它们
重要的环境变量
1) EPICS_CA_ADDR_LIST:
a) 确定到何处搜索
b) 是一个列表(由空格分开):"192.168.50.2 192.168.10.3 192.168.60.255"
c)默认是在主机上所有网络接口的广播地址。当服务器在与客户端相同子网上才有效。
d) 广播地址:
- 发送给在一个子网上所有服务器。
- 示例:192.168.3.255
- 在Linux上使用"ifconfig -a"或"ip address"查找IP地址。
2) EPICS_CA_AUTO_ADDR_LIST:
- YES:在搜索中包含以上默认地址
- NO:不要默认地址上搜索
- 如果你设置了EPICS_CA_ADDR_LIST,通常设置这个为NO。
EPICS_CA_ADDR_LIST
通道访问的过程
在主机上多个IOCs
1) IOCs的IP地址1.1.1.1,所在子网1.1.1.0
- 第一个IOC:UDP 5064, TCP 5064
- 第二个IOC:UDP 5064, TCP ???
2) 尝试从另一个子网搜索
a) EPICS_CA_ADDR_LIST=1.1.1.1
- 不起作用
- 网络内核中奇怪:仅最后启动的IOC才能获取UDP 5064上的东西
b) EPICS_CA_ADDR_LIST=1.1.1.255:正常。当对子网使用广播时,在UDP 5064上的所有IOCs将看到搜索请求。
防火墙
1) IOCs的IP地址1.1.1.1,所在子网1.1.1.0
- UDP 5064, TCP 5064
- UDP 5064, TCP ???
- EPICS_CA_ADDR_LIST=1.1.1.255
2) 防火墙不能打开遇见不到的TCP ???
3) 可能阻塞广播
4)需要运行CA网关
- 防火墙允许对CAGateway的访问
- CAGateway在子网内使用广播
网络中断的处理
没有网络是100%可靠的,因此CA被设计成处理这些:
1) TCP连接被服务器关闭
- 通知客户端代码这个问题
- 操作显示窗口会显示这个问题。
- 客户端发送新的搜索请求
2) 30秒内没有数据或者beacon来自服务器
- 客户端发送"你在那里吗?"请求。
- 如果5秒内没有响应,也通知客户端代码,但TCP连接保持打开来避免网络风暴。
- 如果服务器最终发送数据:正常。否则,我们等待到OS断开了这个TCP连接。
Beacons
1) 由CA服务器发送的UDP广播包
2)当其健康时,每个服务器用规定间隔发送UDP beacon(像心跳)。
EPICS_CA_BEACON_PERIOD=15是默认的。
3) 当它出现时,每个服务器广播一个UDP beacons的启动序列。
- 以一个短间隔开始(~2ms)
- 间隔每次加倍,直到达到15秒
4) 客户端监视这些beacons:
- 接收到beacons:服务器正常。
- 接收到变化间隔的新beacons时:Beacon "异常",新CA服务器,重启搜索。
Beacon看似一个好办法,但:
1) 存档设置可能有很多缺失的PVs:
2) 过载的IOCs或者网络延时可能改变beacon模式为这样:
3) 断开通道的客户端重启它们的搜索。网络流量爆发。
caRepeater?
1) 较老的OS不允许多个程序监听相同的UDP端口:它们看不到这些beacons(UDP广播)
2)caRepeater解决了这个问题:
- 每个工作站仅有一个caRepeater进程。
- 当客户端启动时,它们对其进行建立TCP连接。
- caRepeater接收这些beacons:EPICS_CA_REPEATER_PORT[通常5065],并且转发它们给客户端
问题
1)CA客户端没有连接:检查基本的网络连接。
- 服务器和客户端机器是否能够相互ping通
- 如果服务器在不同子网上,检查EPICS_CA_ADDR_LIST
2) CA客户端在网络问题或者IOC重启后没有重新连接
- 使用casw,wireshark:客户端计算机接收到了重启IOC的(异常)beacons吗?
- 检查EPICS_CAS_BEACON_ADDR_LIST,由于路由器不跨网转发beacons。
- 检查在客户端上是否运行了'caRepeater'。
PV(通道)是什么?
1) 当有一个CA服务器在那里,它决定响应搜索请求时,那就是PV。
2)如果满足以下条件,iocCore响应"{record}.{field}"搜索:
- {record}对应在这个IOC上一个记录,
- {field}是那个记录的一个可访问字段,
- 或者它是伪字段"RTYP"(记录类型)
3) 因此,每个记录的每个字段都是一个PV。
4) 但你可以基于CAS库(对应C++)或者用于python的pcaspy包装器实现你自己的CA服务器,并且接着你决定何时响应。
通道属性
每个通道具有以下这些属性:
1) 值:
- 类型:string,double,int,...
- 标量或数组
2)时间戳:最高纳秒精度
3)严重性代码:OK,MINOR,MAJOR或INVALID
4)使得严重性合格的状态代码:OK,READ错误,WRITE错误,位于HIGH限制,...
5)单位,建议的显示范围,控制限制,警报限制
客户端连接属性
1)可用的属性是固定的。不能添加一个新的‘颜色’属性。
2)请求的类型是固定的。
- "DBR_..."类型
- 可用:仅值;带有状态和严重性的值;带有状态,严重性和时间戳的值;"一切":值,单位,时间,状态,限制,...
3) 不可用:像值和单位的自定义组合。
4)见"caget -h"
记录 和字段对比通道和属性
1) 一个CA客户端请求一个通道的属性
2)CA服务器的实现者决定了如何应答
3)iocCore实现映射一个记录的字段到一个通道的属性:详细情况在各自记录类型的源代码中。不总是可预见或者有意义。
示例:AI记录"fred"
1) PV "fred"或者"fred.VAL"
- 通道的值属性 = 记录的VAL字段:类型double,一个元素(标量)
- 时间属性 = TIME字段
- 状态 = STAT
- 严重性 = SEVR
- 单位 = EGU
- 精度 = PREC
- 显示限制低,高 = LOPR,HOPR
- 控制限制低,高 = LOPR,HOPR
- 警报限制 = LOLO,LOW,HIGH,HIHI
2)很有意义:GUI可以带单位一起显示值,根据精度格式化,如,例如:"12.34 volts"。
3)PV "fred.SCAN"
- 通道的值属性 = 记录的SCAN字段,类型:枚举,值:"Passive", "1 second", ...
'camonitor'将何时接收新值?
1) 当CA服务器(IOC)发送一个新值时!
- 模拟记录:VAL变化>=MDEL
- 二进制记录:每次变化
2) 假设客户端使用'DBE_VALUE'订阅:
- DBE_LOG:用于存档系统。模拟记录变化>=ADEL
- DBE_ALARM:用于警报系统。
数据库通道访问链接标记
1) CA:强制CA链接,即使目标在相同IOC中
2)CP:对于输入链接,在接收到CA monitor时运行。
3)CPP:CP,但仅限SCAN=Passive
允许"如果输入变化,运行记录"。
要记住的点
1) 在99%的情况中,CA "就有效"
- 如果不是,检查EPICS_CA_ADDR_LIST
- 如果不是那样,可能有UDP搜索广播和beacons的子网/路由问题。
2)通道/属性和记录/字段是不同的东西。
这从IOC数据库和其记录类型解耦了CA客户端,允许EPICS合作者共享客户端工具用于不同记录和数据库。但也表示了CA客户端不知道记录和字段。
- 客户端不知道可能有一个随着'设置点'AO记录变化的'回读' AI。
- 存档程序存储通道和其属性,而不是整个AI或电机记录。
- 用于处理waveform记录数据的重要属性完全丢失(采样率,数据类型)。