工业通信核心:IEC 104规约原理、报文解析与工程实践指南

工业通信核心:IEC 104规约原理、报文解析与工程实践指南
1. 项目概述从零开始理解工业通信的“普通话”如果你在电力、轨道交通或者工业自动化领域工作那么“104规约”这个词你一定不陌生。它就像工业通信世界里的“普通话”是连接监控主站调度中心和远方终端变电站、发电厂里的智能设备的标准语言。我最初接触它时面对着一堆十六进制报文和厚厚的协议文档也是一头雾水。但当你真正理解了它的设计思想和报文结构就会发现这套规约设计得相当精妙是保障电力系统“眼睛”和“耳朵”畅通无阻的关键。简单来说IEC 60870-5-104规约我们通常简称104规约定义了在TCP/IP网络之上如何可靠、高效地传输电力系统的遥测YC如电压、电流、遥信YX如开关分合状态、遥控YK如远程操作开关和遥调YT如调整变压器档位这“四遥”数据。它不是一个凭空创造的新协议而是在经典的101规约基于串行链路基础上为适应现代网络化环境而做的“网络化升级版”。理解104规约不仅是掌握一种通信工具更是理解整个远动系统数据流和控制逻辑的基础。无论你是负责系统集成的工程师、进行协议开发的程序员还是负责运维调试的技术人员吃透104规约都能让你在排查通信故障、解析数据含义时事半功倍。2. 核心架构与报文结构拆解要学好104规约不能死记硬背报文而是要先理解它的“骨架”和“语法”。它的设计充分考虑了工业通信对可靠性和实时性的要求。2.1 网络承载与连接管理104规约直接跑在TCP/IP协议栈之上默认端口号是2404。这意味着它天然具备了TCP协议提供的可靠、有序、无差错的数据流传输能力。但工业场景有其特殊性比如网络可能中断对端设备可能重启所以104规约在TCP之上定义了自己的连接管理和超时机制。一个典型的104通信会话始于TCP三次握手建立连接。连接建立后双方会交换“启动帧”U格式帧这是一个不包含应用数据的特殊报文仅用于链路测试和确认。之后主站会发送“总召唤”命令请求终端上传所有的静态数据如所有遥信、遥测的初始值这个阶段完成后系统才进入正常的“变化数据”循环传输或“问答”模式。这里有个关键点TCP连接是长连接。一旦建立除非网络故障或主动断开连接会一直保持。所有104的应用报文都通过这个长连接通道传输。为了检测链路是否“活着”规约定义了t0、t1、t2、t3等一系列超时参数。例如t1是发送方等待接收方确认的超时如果超时未收到确认发送方会重发报文t3是链路空闲测试时间当超过t3时间没有应用报文需要发送时发送方会主动发一个U格式的“测试帧”如果对端没有响应则认为链路中断。这些参数需要在主站和终端侧协调配置配置不当会导致频繁的误报警或连接中断。2.2 三种报文格式I/S/U格式详解这是104规约的核心“语法”。所有报文都遵循统一的APCI应用协议控制信息头后面可能跟着ASDU应用服务数据单元。I格式报文信息传输格式这是承载实际“四遥”数据的报文是通信的主体。它的APCI头里有两个至关重要的序号发送序号Send Sequence Number, N(S)和接收序号Receive Sequence Number, N(R)。这借鉴了TCP滑动窗口的思想但工作在应用层。N(S)表示当前发送的I帧的序号。每发一个新的I帧N(S)加1。N(R)表示发送方已经正确收到的、对端发来的最后一个I帧的序号加1。换句话说“我已经收到了你N(R)-1及之前的所有I帧”。这个序号同时作为对已收到报文的确认ACK。这种“捎带确认”机制非常高效。例如终端在给主站上报一个变化遥信I帧时可以顺便在N(R)里确认刚才主站发来的遥控选择命令。I格式报文必须被确认否则发送方会在t1超时后重发。S格式报文确认格式这是一个“纯确认”报文。当一方收到了一批I帧但暂时没有新的I帧数据需要发送给对方时为了不让对方因等待确认而超时重发就需要单独发送一个S格式报文。S格式报文里只包含N(R)用于确认之前收到的所有I帧。它不携带ASDU非常简短。U格式报文控制格式用于链路的启动、停止、测试等控制功能不携带ASDU也不参与序号确认。常见的U帧类型有STARTDT启动数据传输在TCP连接建立后由主站或终端发出激活数据传输阶段。只有收到对端的STARTDT确认后才能开始发送I格式报文。STOPDT停止数据传输暂停数据传输但不断开TCP连接。TESTFR测试帧用于链路空闲测试t3超时机制。收到TESTFR后必须立即回复一个TESTFR确认。注意在实际抓包分析时务必分清这三个格式。一个常见的错误是看到大量S帧就认为通信异常。实际上在数据变化不频繁时S帧是维持链路健康、避免无用重传的正常报文。而如果长时间只有U帧TESTFR交互没有I帧则可能意味着应用层没有数据需要传输需要检查终端数据是否正常刷新或主站召唤设置。2.3 ASDU结构数据信息的“集装箱”I格式报文里装着的“货物”就是ASDU。它是规约中真正定义数据含义和格式的部分。一个ASDU结构复杂但规整主要包含类型标识Type Identification, TI1个字节定义了ASDU的类型。这是解析数据的钥匙。例如1单点遥信M_SP_NA_19测量值归一化值M_ME_NA_145单命令C_SC_NA_1遥控100总召唤命令C_IC_NA_1记住常用TI看报文就成功了一半。可变结构限定词VSQ1个字节最高位表示信息元素是连续的还是离散的低7位表示本ASDU中包含的信息元素数目。例如VSQ0x81二进制10000001表示有1个连续地址的信息元素VSQ0x07表示有7个离散地址的信息元素。传送原因Cause of Transmission, COT1或2个字节说明这个数据是为什么传送的。常见原因3突发自发上传如开关变位4初始化总召唤响应5请求被主站召唤后响应6激活命令的激活如遥控选择7激活确认对激活的确认10激活终止命令执行完成通过COT可以清晰判断一个报文是主动上报、响应命令还是命令本身。公共地址Common Address, COA通常2个字节代表终端RTU/FTU的站地址。主站通过这个地址来区分数据来自哪个厂站。信息对象地址IOA通常3个字节这是数据点在终端内部的唯一逻辑地址。比如1号开关的遥信地址可能是0x0000011号线路的A相电流遥测地址可能是0x400001。主站和终端的数据库必须对IOA的定义完全一致否则会出现“张冠李戴”。信息元素Information Object数据的本体。对于遥信可能是1个比特0分1合对于遥测可能是2个字节的归一化值或4个字节的浮点数对于遥控包含单/双命令、执行/撤销等元素。理解ASDU各字段的含义是进行协议开发、数据对点和故障排查的基础。当你拿到一份报文能迅速说出“这是一个由3号站突发上传的、包含2个离散地址单点遥信的状态信息其中地址0x000100的开关为合位”那你就真正入门了。3. 核心通信过程与交互场景实录纸上得来终觉浅我们结合几个最核心的交互场景看看报文是如何“活”起来的。3.1 初始化与总召唤过程这是通信建立后的第一个重要阶段目的是让主站获取终端所有数据的完整“快照”。TCP连接建立主站客户端向终端服务器端口2404发起TCP连接。启动数据传输主站发送U格式STARTDT激活报文终端回复STARTDT确认。总召唤启动主站发送一个I格式报文其ASDU类型为100C_IC_NA_1传送原因6激活信息对象地址通常为0x0000。这是一个“总召唤激活”命令。终端确认激活终端收到后回复一个相同类型、相同地址的ASDU但传送原因改为7激活确认。这表示“你的总召唤命令我收到了开始执行”。终端上传数据终端开始按顺序上传所有静态数据。先上传所有遥信TI1 COT4再上传所有遥测TI9 COT4。每个ASDU的VSQ决定了它一次上传几个点。这个过程可能持续数秒到数分钟取决于终端的数据规模。总召唤结束当所有数据上传完毕后终端发送一个类型为100的ASDU传送原因改为10激活终止表示总召唤执行完毕。实操心得总召唤过程非常消耗网络带宽和终端资源。在系统运行期间不应频繁进行。通常只在通信初始化、主站重启或主站检测到大量数据不一致时执行。日常运行主要依靠变化数据上传突发。在调试阶段可以通过抓包观察总召唤流程是否完整来验证主站和终端的基础通信与数据配置是否正确。3.2 变化数据突发上传这是系统正常运行时最主要的通信方式保证了数据的实时性。场景变电站内101号开关由“分”变为“合”。过程终端检测到开关变位。终端立即组装一个I格式报文。ASDU类型为1单点遥信传送原因为3突发信息对象地址为0x000065假设101号开关的地址。终端将该报文放入发送缓冲区并通过已建立的TCP连接发送给主站。主站收到后更新数据库和画面并在下一个需要发送给终端的I帧中可能是遥控命令也可能是召唤报文通过N(R)字段对这个变位报文进行确认。如果主站暂时没有数据要发则会单独发送一个S格式报文进行确认。这种“事件触发”的传输模式使得主站能近乎实时地感知现场状态变化网络流量也远小于周期轮询。3.3 遥控选择-执行过程详解遥控是104规约中最体现其可靠性的过程采用严谨的“选择-执行”两步法防止误操作。选择预置命令主站操作员在画面上点击“分闸”操作。主站发送一个I帧ASDU类型为45C_SC_NA_1传送原因6激活信息对象地址为开关地址如0x000065信息元素里包含“选择”标识和“分闸”命令。终端收到后进行一系列校验地址是否有效、对象是否允许遥控、当前状态是否允许此操作等。如果校验通过终端锁定该对象并回复一个镜像报文。这个回复报文的ASDU类型、地址、命令信息与主站发来的完全一致但传送原因改为7激活确认。这表示“选择成功对象已就绪等待执行命令”。如果校验失败终端回复的传送原因可能是47未知信息对象地址等。执行命令主站收到成功的“选择确认”后操作员点击“执行”按钮或由系统自动延时执行。主站再发送一个I帧ASDU类型仍为45传送原因改为6激活信息元素里包含“执行”标识和“分闸”命令。终端收到执行命令后驱动物理继电器出口真正执行分闸操作。操作完成后终端回复一个ASDU传送原因改为10激活终止表示“命令已执行完毕”。同时开关的遥信状态会通过一次突发上传COT3通知主站。撤销命令如果在“选择”之后、“执行”之前操作员取消操作主站会发送一个传送原因为8停止激活的ASDU终端收到后解除对该对象的锁定并回复一个传送原因为9停止激活确认的报文。注意事项“选择-执行”机制是安全底线。任何直接一步到位的“遥控”实现都是不符合104规约标准且危险的。在调试遥控时务必通过抓包确认这两个步骤的报文交互是否完整、正确。终端回复的“激活确认”和“激活终止”是判断遥控成功与否的关键标志而不是仅仅看画面状态变化状态变化可能因通信延迟稍后到来。4. 关键参数配置与工程实践要点协议理解透了落地到具体项目和产品上参数配置就是决定通信稳定性的“临门一脚”。配置不对轻则通信不畅重则系统瘫痪。4.1 超时参数t0, t1, t2, t3, k, w配置指南这些参数需要在通信双方主站和终端协调配置通常主站侧作为主动方参数起主导作用。参数名默认值秒含义配置要点与影响t030连接建立超时。TCP连接建立后等待STARTDT交换完成的超时时间。网络状况好可适当减小。如果终端启动慢可能需要调大避免连接刚建成就因超时被断开。t115发送方等待I帧确认的超时。最关键参数之一。小于网络往返时间RTT会导致无谓的重发增大网络负担过大则故障响应慢。在局域网通常设2-5秒跨广域网需根据实际延迟调整可能需10-30秒。t210接收方等待发送数据的机会以便捎带确认。当一端收到数据如果它在t2时间内有数据要发给对方就可以用I帧捎带确认否则必须发S帧。通常设为t1的2/3左右。t320链路空闲测试周期。当超过t3时间没有应用层I帧数据需要发送时发送方会发U格式TESTFR。此值应大于t1。设置过短会产生大量测试帧过长则无法及时发现链路中断。k12未被确认的I帧最大数目发送窗口。窗口大小。k值大吞吐量高但接收端缓冲区压力大且发生批量重传时影响大。典型值8-12。w8接收窗口大小。接收方能缓存的、未处理的最大I帧数。通常wk。配置黄金法则t1 t2 t3。必须严格遵守这个不等式否则定时器逻辑会混乱。最实用的方法是在项目初期通过ping命令或抓包工具测量一下主站与终端之间的网络平均延迟和抖动以t1 3 * RTT作为初始值进行配置然后根据实际运行日志观察重发情况做微调。4.2 站地址与信息地址规划这是数据能否正确对接的核心。公共地址COA通常范围是1~65535。0地址一般保留为广播地址慎用。在一个系统中每个终端的站地址必须唯一。主站根据这个地址来路由数据。有些系统设计会用站地址来区分不同的物理子站或逻辑分区。信息对象地址IOA3字节范围0x000000~0xFFFFFF。这是规约层面的逻辑地址需要与终端内部的点表数据库一一对应。规划建议采用分段规划。例如0x000001-0x001FFF分配给遥信点如开关、刀闸、告警信号。0x400000-0x40FFFF分配给遥测点如电流、电压、功率。0x600000-0x6000FF分配给遥控点。0x700000-0x7000FF分配给遥调点。这样规划的好处是通过地址就能判断数据类型便于维护和排查。务必形成详细的《点表设计文档》作为主站和终端开发、调试的共同依据。4.3 平衡式与非平衡式传输这是104规约两种基本的通信模式决定了数据流的主导方。非平衡式传输这是最常用的模式。主站是绝对的主导者客户终端是被动的响应者服务器。所有通信由主站发起包括周期召唤、总召唤、遥控命令等。终端只有在发生变化如开关变位时才能主动发起“突发”上传。这种模式结构清晰主站容易管理所有终端的通信节奏和资源。平衡式传输通信双方主站和终端在协议层面是对等的都可以主动发起通信连接和传输数据。这种模式更复杂通常用于主站与主站之间的数据交换如不同调度中心之间的数据转发在常规的主站-终端RTU场景中极少使用。实操心得99%的工程应用都是非平衡式。在配置工具或代码中你会看到“传输模式”的选项选择“非平衡”即可。如果误选为“平衡”而对方是按非平衡实现的通信将无法建立。判断一个设备是平衡还是非平衡一个简单的方法是看它能否作为客户端主动向外发起TCP连接。标准的终端服务器只能监听端口等待主站连接。5. 开发与调试实战从抓包到问题定位理论最终要服务于实践。无论是开发104驱动还是现场调试通信问题抓包分析都是无可替代的“终极武器”。我习惯使用Wireshark这款工具。5.1 Wireshark抓包与104解析过滤器设置抓包位置最好在主站服务器或终端设备的网络接口上抓包。如果在交换机上做端口镜像抓包能看到双向流量更理想。启动Wireshark选择正确的网卡开始抓包。应用104解析器Wireshark默认可能不将2404端口识别为104协议。抓包后在任意TCP报文上右键 - “Decode As...”在弹出的对话框中选择“TCP”端口“2404”将其解码为“IEC 60870-5-104”协议。使用显示过滤器在过滤器栏输入iec60870_5_104可以只显示104协议报文。更精细的过滤例如iec60870_5_104.type 0x03查看I格式帧。iec60870_5_104.cot 3查看突发数据。ip.src 192.168.1.100 iec60870_5_104查看特定IP发出的104报文。5.2 典型通信问题排查流程与案例当通信中断或数据异常时遵循从底层到高层的排查思路。案例一TCP连接频繁断开现象主站与终端反复连接日志显示“连接断开”或“t3超时”。排查抓包过滤双方IP观察TCP握手SYN, SYN-ACK, ACK是否成功。如果失败是网络链路或防火墙问题。观察104交互连接建立后是否有STARTDT激活与确认如果没有可能是某一方协议栈未正确初始化。检查t3超时观察在长时间无I帧数据期间是否有U格式的TESTFR测试帧和TESTFR确认的交互。如果只有一方发TESTFR另一方无回应则接收方可能已死机或网络单向中断。最常见的原因是对端设备的t3参数配置不一致或对端设备处理TESTFR的逻辑有bug。检查Keep-Alive有些操作系统或网络设备会设置TCP Keep-Alive时间如果小于104的t3可能会在应用层认为链路还健康时底层TCP连接已被断开。需要协调调整。案例二遥控失败但选择成功现象主站下发选择命令终端确认成功但下发执行命令后终端无响应或返回错误开关未动作。排查抓包确认流程确认选择、执行两个报文的ASDU类型、地址、命令类型选择/执行、传送原因是否完全正确。特别注意执行报文的“激活”原因是否发送。检查终端日志终端在收到执行命令后其应用层逻辑是否真正驱动了出口继电器是否有“遥控闭锁”信号如就地/远方切换开关在就地位置这是最常见的原因。检查返校超时主站下发执行命令后会等待终端的“激活终止”回复。如果这个等待时间通常是一个独立的参数不同于t1设置过短可能在终端操作完成前就超时了主站报“遥控超时”失败但实际上终端可能已执行。案例三遥测数据值不对现象主站画面显示的电流、电压值与现场表计相差很大。排查抓包看原始值在Wireshark中展开ASDU找到对应的遥测信息对象查看其“值”字段的原始字节。例如一个电流值在报文中可能是0x2A 0x00两个字节。核对转换规则104规约中遥测值有多种表示方式归一化值、标度化值、短浮点数。必须确认主站和终端采用的规则一致。例如对于“归一化值”其计算公式通常是实际值 (报文原始值 * 额定因子) / 32768。如果终端按此规则发送主站却按浮点数解析结果必然错误。核对系数和基值即使规则一致还有标度变换系数scale和偏移量offset需要核对。这些参数通常在工程配置中设置必须两端匹配。字节序问题对于多字节整数或浮点数要确认是大端序Big-Endian还是小端序Little-Endian。104规约标准规定是低字节在前小端序但有些老旧或不规范的设备可能反着来。5.3 自制简易调试工具的心得除了商用协议测试软件有时自己写个小工具非常高效。我用Python的socket库和struct模块写过简单的104主站模拟器和报文解析器。核心思路建立TCP连接作为客户端连接终端的2404端口。组包按照104的APCI和ASDU格式用struct.pack函数将各个字段起始字节0x68、长度、控制域、类型标识、VSQ等按顺序打包成字节流。控制域中N(S)和N(R)的计算是重点。发包通过socket发送字节流。收包解析接收数据先用struct.unpack解析APCI头根据长度字段读取完整的ASDU再按格式解析。这样做的好处精准控制可以手动构造任何你想测试的报文比如一个非标准的传送原因来测试终端的容错性。深入学习在组包和解包的过程中你对每一个比特位的含义会有刻骨铭心的理解。快速验证当怀疑商用主站软件有问题时可以用自己的工具发送一个标准报文看终端如何响应快速定位是主站问题还是终端问题。当然生产环境一定要用成熟稳定的商业或开源库。但自己动手实现一遍是理解协议精髓的最佳途径。

最新新闻

日新闻

周新闻

月新闻