PROFINET的非周期通信,是想了又想,拖了又拖,终于鼓足勇气写一下。跟Ethercat和Canopen一样,任何一种完备的协议都不可能所有的内容通过过程数据解决。Ethercat有SDO数,对比于PROFINET,就是非周期,简称RTA。按通信带宽的划分,分为RT,IRT,RTA,NRT,(SYN),当然现在网上怎么划分的都有。非周期使用IEEE802.3或者RTA-UDP协议。我觉得还是回归到最原始的网络分层模型,如图1所示,为经典网络模型,在《Profinet协议解析-过程数据》这篇文章中曾经提到过相似的系统模型。

如上的系统模型,PROFINET网络将系统分为普通以太网部分,实时数据部分。普通以太网部分包含:物理层,链路层,网络层…应用层,通过该通道,可以实现正常办公和互联网各种应用的通信。这样做的好处在于可以完全兼容现有的以太网,像摄像头,打印机和语音数据等都可以通过从站或主站的构建网络进行通信,不必另辟物理链路,同时还支持了IEEE 802.11无线协议,更方便的进行组网,所以在应用层支持的内容非常多,常见的HTTP,SNMP,DHCP,LLDP,PING,FTP等都可以实现,也就省去了Ethercat的FOE、EOE等外挂方式,这一点大家可以大胆尝试,放开手脚使用。实时数据部分包含RT,IRT和未来的TSN,为了保证网络数实时性,PROFINET-RT砍掉了网络层,直接构建了链路层到应用的直通,在最大程度上保证数据及时的传递到目的站点。IRT在RT的基础上,修改了交换桥,在硬件上保证实时性和通道专用,所以同步程度跟高,未来TSN在千兆网络上运行,可以将同步周期降到31.25us。我们这里主要讲RTA, 通过图1最左侧的通道,RTA-UDP正常来讲是可以路由的,因为经网络层传输。如图2所示,其数据帧分链路层,IPv4,UDP,通过RPC协议实现具体的PROFINET IO操作,既然有了IP地址,就可以进行路由,访问驱动器参数,但实际是不可行的,因为在访问前主站需要识别设备,依赖DCP协议,详见文章《PROFINET协议解析-DCP》,由于DCP只能在链路层,所以无法正常工作,自然就轮不到非周期数据的运行了。后面专门写一篇文章介绍PROFINET主站的启动过程,这里就不展开了。

非周期采用的UDP协议,为了保证可靠性连接,使用类似TCP的握手机制,所以传输效率低。具体的为一问一答的形式。例如访问一个参数P12345,看如下对话:
PLC : 620xx的设备,给我你的12345参数,我要参数值
620xx: 收到,我已经给你准备好数据了。
PLC: (传输完RT,IRT等数据),我有空了,给我数据吧
620xx: 没空,等会。
PLC:好了没?给我数据。
………………….
620xx: 12345的参数值就是这个。
以上就是一个完整的参数访问,在这个过程中PLC和620xx多次对话,受限于620xx和PLC的运行周期不同,有可能一次性访问失败,只要在超时范围内都可以正常进行应答。
非周期协议帧如下表所示,共分为两个部分,其中PROFINET部分只是嵌入到以太网的数据中而已。最后的校验仍数据以太网协议帧的校验。以太网的数据帧就像洋葱一样,一层包裹一层,最外层的是链路层,通过MAC地址进行寻址。中间数据部分正常嵌入网络层,也就是TCP/IP数据,网络层部分中的数据区域继续嵌入应用层数据,例如HTTP等,就组成了我们常见的网路数据帧。这帧数据每到交换机就会看有没有VLAN划分,优先级情况进行转发;当遇到路由器时,又会剥出TCP/IP数据,查看目的IP网段 ,进行路由转发;当遇到浏览器时,会解析出HTTP的数据,展示在我们面前。当然,传递这类视频类或网站类数据都比较大,当一帧无法处理时,超过1440个字节,就会分包,这是TCP/IP的机制,再展开就比较复杂了。当以以上这种方式处理数据时,必然在解析时和交换数据时浪费过多的时间,影响数据的实时性,所以RT和IRT就直接使用了链路层数据,IRT因为具备专用通道,干脆干掉了VLAN,协议帧变得更为简洁,实时性得到了保证。
以太网部分 | PROFINET部分 |
| ||||||||
前导码 | 帧开始 | 目的MAC | 源MAC | 以太网类型 | VLAN | 以太网类型 | 帧ID | 数据 | 状态 | 校验 |
7 Bytes | 1 | 6 | 6 | 2 | 2 | 2 | 2 | 40-1440 | 4 | 4 |
言归正传,这里的非周期数据,因为对实时性没有要求,所以使用了最原始以太网传输方式,如图2所示,在数据区部分嵌入了多层,依次是网络层-UDP协议,会话层-RPC,应用层-Profinet RTA。我们常用或者驱动层开发看到的基本用来访问从站的参数和诊断通道,RTA在启动时对AR,I&&M,诊断,日志,PDPort等都有所操作,通过协议帧内的请求头的Index进行识别。如图3为访问数据的部分截图。这是subslot的一部分,共分为API,Slot,Subslot,Profisafe,profidrive,AR和Device。所以RTA使用非常多,尤其在初始化过程中。PLC通过DCP查找到从站后,利用非周期建立AR,并传递必要的CR,以便进行后续的工作。对于轴类型的设备,后续会根据应用类继续访问必要的驱动器参数,以便正确的初始化编码器和通用状态机等等。可以说用途广泛,不可或缺。

说了这么多,可能会有疑问,为什么还没有真正的解析一帧完整的RTA数据。之前讲过,RTA非常复杂,一层套一层,解析起来难度系数不低,所以建议大家充分利用Wirshark工具,毕竟我们不是专门搞协议的,所以利用好工具本身就是一种进步,事半功倍。这里我拿一个例子简单拆分一帧数据,从宏观上来讲一下。下面这帧数据,目的是向驱动器请求访问5个行规参数。
080000001010286336caf97c0800450000cabc98000040113c37c0a80001c0a80002fd8fc00300b60ac904002000100000000000a0de976cd11182710001000f044d0100a0de976cd111827100a02442df7d282f0606000010108000286336caf97c02000000010000001f0000000300ffffffff5e00000000004a0000004a0000004a000000000000004a0000000008003c01000027dda434584259fb44a844d6a36220609e00003a00000100020000b02e0000000a0000000000000000000000000000000000000000000000000d0100011000039a00000101051000004000704f03ab0a000000
拆分为链路层数据,网络层数据,会话层数据,应用层数据。
链路层:
全部
网络层-UDP:
450000cabc98000040113c37c0a80001c0a80002fd8fc00300b60ac904002000100000000000a0de976cd11182710001000f044d0100a0de976cd111827100a02442df7d282f0606000010108000286336caf97c02000000010000001f0000000300ffffffff5e00000000004a0000004a0000004a000000000000004a0000000008003c01000027dda434584259fb44a844d6a36220609e00003a00000100020000b02e0000000a0000000000000000000000000000000000000000000000000d0100011000039a0000
会话层-RPC:
04002000100000000000a0de976cd11182710001000f044d0100a0de976cd111827100a02442df7d282f0606000010108000286336caf97c02000000010000001f0000000300ffffffff5e00000000004a0000004a0000004a000000000000004a0000000008003c01000027dda434584259fb44a844d6a36220609e00003a00000100020000b02e0000000a0000000000000000000000000000000000000000000000000d0100011000039a0000
应用层-PROFINET:
- 4a0000004a0000004a000000000000004a0000000008003c01000027dda434584259fb44a844d6a36220609e00003a00000100020000b02e0000000a0000000000000000000000000000000000000000000000000d0100011000039a0000
- 请求头部-IODWriteResHeader:
BlockType | BlockLength | blockVersion | Seq | ARUUID | API |
0x0008 | 0x003c | 0x0001 | 0x27 |
| 0x00003a00 |
Slot | Subslot | padding | Index | Record Len | padding |
0x0001 | 0x0002 |
| 0xb02e | 10 |
|
0008003c01000027dda434584259fb44a844d6a36220609e00003a00000100020000b02e0000000a000000000000000000000000000000000000000000000000
- Profidrive部分
Reference | Id | Do | Parameter Num |
0x0d | 0x01 | 0x0 | 0x1 |
Attribute | numberofparameter | parameter | index |
0x10 | 0 | 0x39a | 0 |
0d0100011000039a0000
可以看出我们实际有用的就是为了传递Profidrive这几个字节的数据,仍然需要外围几十倍之多的数据来保证网络上的传递需求。以上就可以形象的展示整个洋葱的感觉,一层剥去,数据少一部分,知到解析最后,数据结束。在每一个分层上都有相应的数据校验来保证数据的完整和准确性。整个数据非常庞大,同样的带宽下,往往过快的非周期访问会给整个网络带来不小的负载。有兴趣的同学可以通过对照wirshark或者PROFINET 协议标准IO类型10的规范进行一点一点解析,每一个索引或ID在当前帧时什么,还会对应哪些其他的内容,都可以在协议中满足你的好奇心。由于以太网的复杂性,所以通过电脑抓包时,电脑的网卡环境,以及交换机路由器都会或多或少的影响到数据帧,可能发现多了VLAN,有时候又没有,这都是正常的。
非周期数据的操作并非向任意一台机器发起握手请求就可以连接的,在访问之初,需要通过DCP识别这台设备,然后通过非周期的Connect(如下表)建立连接,再之后才是发起请求进行访问,用起来也比较麻烦。非周期的操作由RPC中进行传递,总共五种操作。
Op Num | 指令 | 意义 |
0 | Connect | 建立连接 |
1 | Release | 释放连接 |
2 | Read | 读操作 |
3 | Write | 写操作 |
5 | Read Implicit | 隐式访问 |
由于非周期数据使用OSI的链路层、网络层、会话层到应用层,基本上覆盖了整个模型,所以后期也不会有改动的空间,其向以太网的兼容性已经做到了全覆盖,即使在V2.4版本的协议集成TSN后,也是对IRT的补充,再也不会去影响这种非周期部分。这部分内容就先写这么多,如果展开来说,可能涉及的内容过多,仅RTA层面就包括正响应,负响应,数据,错误。其下一层又根据BlockType划分为IODWriteReq,IODWriteRes, IODReadxxx, IOCxx, Alarm, IM…… 如上图3中所列出的一小部分。上面的例子中我们仅介绍了IODWriteReq进行最简单的解析示意。有兴趣的小伙伴可以自己借助工具自己分析,或者自己组帧,并由链路层发出去,尝试与某一台从站建立连接,避开DCP的限制,尝试下能否成功实现。不知不觉,已经工作了快接近两年的时间了,从最初毕业的懵懂无知,到偶然间接触到PROFINET这个协议,也算是一种幸运。自己从小就对互联网比较感兴趣,无奈自己坚持实业工作,也就不会挂钩互联网,经过一段时间的了解,越来越对PROFIENT感兴趣,因为它可以完全兼容以太网,之前的WebServer也在博图上实现过,甚至西门S210的后台也是Web形式,给了我这个在工业领域互联网迷恋者一点曙光。希望自己掌握的Web技术也能有一天应用在自己负责的驱动器平台上,尽我所能为国家的工业发展做出一点点小小的贡献。博客:https://blog.csdn.net/zh_666888/ 这是我的博客,欢迎评论区共同交流。现在我们的社区越来越多的人随意转发文章,之前发的几篇博客也是被各种网站的爬虫抓的漫天飞。我觉得对内对外都不好,浪费大家时间,检索下来,打开不同的网站全是同一个资源,对网站未来的发展也不好。如果有问题可以在评论区交流,我看到后会及时答复的,也希望西门子能够以Open的姿态开放生态圈,允许更多的开发人来完善补充,充满活力。