IEC104规约解析:电力SCADA系统的核心通信协议与调试实战 1. 从“黑话”到“普通话”IEC104规约到底是什么如果你在电力自动化、新能源场站或者工业控制领域待过一阵子肯定听过“IEC104规约”这个词。它就像圈子里的“黑话”老工程师们张口就来但很多刚入行的朋友尤其是从IT或互联网转过来的一听就懵这到底是啥一个协议一个标准还是某种神秘的通信咒语简单来说IEC104规约是电力系统运动通信的“普通话”。想象一下在一个庞大的电网里有成千上万个设备发电厂的风机、光伏逆变器、变电站的断路器、保护装置、调度中心的主站系统。它们之间需要实时交换数据比如“1号断路器当前是分闸还是合闸”“A线路的电流是多少”“请立即执行遥控分闸命令”。如果没有一套统一的语言A厂家的设备说“Hello”B厂家的设备回“Bonjour”那整个系统就乱套了根本无法协同工作。IEC104规约就是这套统一的语言。它的全称是IEC 60870-5-104是国际电工委员会IEC制定的一个标准。这个标准定义了一套非常具体的“语法”和“词汇表”规定了数据如何打包、如何发送、如何确认、出错后怎么办。所有遵循这个标准的设备无论来自哪个厂家都能互相听懂实现无缝通信。它的核心应用场景就是调度自动化系统也就是我们常说的SCADA数据采集与监控系统。主站调度中心通过IEC104规约可以“问”遍全网所有的子站变电站、发电厂获取实时遥测如电压、电流、遥信如开关状态并下发遥控、遥调命令。为什么它这么重要因为在电力行业稳定和可靠是生命线。通信中断几分钟就可能意味着调度员对电网状态“失明”进而引发严重的运行风险。IEC104规约经过几十年的发展和实践形成了一套极其稳定、可靠、且经过充分验证的通信机制。它基于标准的TCP/IP网络这让它在拥有传统电力通信可靠性的同时又具备了现代网络部署的灵活性。所以无论你是从事电力二次系统开发、运维还是做新能源电站的通信调试IEC104都是必须跨过去的一道坎。这篇文章我就以一个趟过无数坑的“老通信兵”视角带你彻底拆解IEC104从协议帧结构一直讲到实际调试中的“玄学”问题。2. 拆解协议帧104规约的“基因编码”要理解一个协议最直接的方式就是看它的“基因”——协议数据单元APDU。IEC104的APDU结构清晰且严谨是它稳定性的基石。一个完整的IEC104 APDU由两部分组成启动字符Start Character和应用规约数据单元ASDU。但更常见的理解是将其分为APCI应用规约控制信息和ASDU应用服务数据单元两层。2.1 APCI通信的“心跳”与“物流管理”APCI负责管理通信链路本身确保数据包能有序、可靠地送达。你可以把它想象成物流公司的调度单上面不关心运送的货物数据具体是什么只关心这个包裹的编号、总共有多少包裹、我收到你第几个包裹了。一个标准的APCI长度是6个字节或4个字节用于U格式帧它包含几个关键字段启动字符68H固定为0x68就像一个信封上的特殊标记告诉接收方“嘿注意了一个IEC104报文开始了”APDU长度1个字节表示后面整个ASDU部分的字节长度。注意它不包括启动字符和自身这1个字节。这意味着一个104报文的总长度 1启动字符 1长度字段 “长度字段”的值。控制域Control Field4个字节这是APCI的灵魂。它决定了这个报文是干什么用的。104规约定义了三种格式的帧对应控制域的不同解读I格式帧信息传输格式这是真正携带业务数据ASDU的帧。它的控制域包含两个重要的序号发送序号N(S)和接收序号N(R)。N(S)表示“这是我发出的第几个I帧”N(R)表示“我期望收到你发出的第几个I帧”。通过这两个序号通信双方实现了带确认的窗口滑动机制这是104可靠传输的核心。S格式帧确认格式当一方收到一批I帧后如果暂时没有数据要发送就会发一个S帧来确认。S帧的控制域只包含N(R)意思是“你发的序号在N(R)之前的所有I帧我都收到了”。这避免了为每个I帧都单独回复确认的开销。U格式帧控制格式用于建立和维护链路不携带ASDU。常见的有STARTDT启动数据传输主站发送意思是“链路已建好现在可以开始传业务数据了”。STOPDT停止数据传输主站发送意思是“暂停业务数据传输但链路保持”。TESTFR测试帧双方定期发送用于确认链路是否还“活着”心跳。注意很多调试问题就出在控制域的理解上。比如子站发了数据I帧但主站一直没有回复S帧或带N(R)的I帧来确认子站的发送窗口就会卡住不再发送新数据。这时候就需要检查主站的处理逻辑是否正常发出了确认。2.2 ASDU业务数据的“集装箱”当APCI这个“物流单”准备就绪ASDU就是里面装载的“货物集装箱”。它定义了数据的具体含义。ASDU的结构同样标准化类型标识Type Identification, 1字节这是最重要的字段之一。它指明了这个ASDU里装的是什么类型的“货物”。比如1单点遥信开关分/合9测量值规一化值带品质描述的短浮点数45单点遥控命令C_SC_NA_1100召唤全数据总召唤103时钟同步命令 这个字段直接决定了后续信息体该如何解析。可变结构限定词VSQ, 1字节它指明了信息体的组织方式。最高位表示是否带顺序号104中通常为0表示不带顺序低7位表示信息体元素的数量。例如VSQ0x81表示带顺序号有1个信息体VSQ0x07表示不带顺序号有7个信息体即一个报文中打包了7个同类型的数据。传送原因Cause of Transmission, 1或2字节这个字段解释了为什么发送这个数据是理解数据流的关键。它也是排查问题的重点。常见的原因有3突发自发—— 设备状态变化时主动上报。5被请求—— 响应主站的召唤命令。6激活—— 主站下发遥控“选择”命令时使用。7激活确认—— 子站确认收到了“激活”命令。8停止激活—— 主站下发遥控“撤销”命令时使用。10激活终止—— 遥控执行超时或失败时使用。20响应站召唤—— 响应主站的站召唤命令。公共地址Common Address, 1或2字节通常指子站RTU/综自系统的站地址。用于在一个通信链路上区分多个子站虽然一条TCP连接通常只对应一个子站但地址字段保留。信息体地址Information Object Address, 3字节这是数据点的“身份证号”。比如变电站里1号主变的101开关它的遥信点号可能被定义为0x000065十进制101。主站和子站的数据库必须对这个地址的定义完全一致否则就会出现“张冠李戴”——主站以为收到了101开关的状态其实是102开关的。信息体元素Information Object Element数据本身。其格式由类型标识决定。比如对于单点遥信类型标识1信息体元素就是1个字节最低位表示状态0分1合其余位可能表示品质描述如是否无效、是否被取代等。对于测量值类型标识9则是4个字节的短浮点数IEEE 754标准加上2个字节的品质描述。一个完整的解析示例假设我们收到一个报文ASDU部分解析出类型标识9 VSQ0x011个信息体传送原因3突发公共地址1信息体地址0x000001信息体元素0x42280000浮点数42.0。那么这个报文的意思是“站址为1的子站主动上报突发了地址为1的测量点其当前值为42.0可能是42.0kV或42.0A。”3. 连接与对话104规约的通信流程实战理解了单个报文的“基因”我们再来看看它们如何协作完成一次完整的“对话”。IEC104的通信流程有着严格的步骤就像两个人打电话有一套固定的礼节。3.1 链路建立从“握手”到“开工”TCP连接建立这是基础。主站客户端主动向子站服务器端默认端口2404发起TCP三次握手。这一步失败所有后续都免谈。失败原因通常是网络不通、子站服务未启动、防火墙拦截。链路测试TESTFR连接建立后双方可能会先发送U格式的TESTFR确认帧探测链路是否可用。有些实现会省略此步直接进入下一步。启动数据传输STARTDT这是最关键的一步。主站发送U(STARTDT act)帧子站必须回复U(STARTDT con)帧进行确认。只有完成这个握手双方才能开始传输携带业务数据ASDU的I格式帧。如果没有收到STARTDT con就发数据对方是不会处理的。总召唤总查询链路激活后主站为了获取子站的全数据即所有遥信、遥测的当前状态会发起一个“总召唤”。它发送一个类型标识为100C_IC_NA_1的ASDU传送原因一般为6激活。子站收到后回复一个相同的ASDU传送原因改为7激活确认表示“收到召唤令开始准备数据”。接着子站会将所有需要上传的数据点以被请求传送原因5的方式分批打包发送给主站。发送完毕后子站再发一个类型标识100的ASDU传送原因改为10激活终止告诉主站“你要的全数据都发完了”。至此主站获得了子站的一个完整数据“快照”。3.2 常态运行突发、循环与命令总召唤完成后系统进入常态运行数据交互主要有三种模式突发自发传输这是最重要的实时数据来源。当子站某个状态发生变化如开关变位它会立即主动上送一个I帧传送原因3突发。主站必须及时处理并回复确认通过S帧或I帧的N(R)。为了保证关键信号不丢失104规约要求对于如开关变位这类信息需要连续发送两次且第二次的ASDU中信息体元素的品质描述字节的“重复”位要置1。循环定时传输子站按照预设的周期如每5秒主动上送一部分重要的测量值如母线电压、频率传送原因通常也是3。这为主站提供了稳定的数据刷新。命令传输遥控、遥调这是主站对子站的“下令”过程流程最为复杂采用“选择-执行”或“直接执行”模式且每一步都有严格的确认。选择-执行模式常用 a. 主站发送“选择”命令类型标识45单点遥控或46双点遥控传送原因6激活信息体中包含对象地址和命令状态分/合。 b. 子站检查命令合法后回复“选择确认”相同的类型标识和地址传送原因7激活确认信息体中包含相同的命令状态。 c. 主站收到选择确认后发送“执行”命令类型标识相同传送原因6激活但信息体中的命令状态会带一个“执行”位通常是一个单独的字节或标志。 d. 子站执行操作并回复“执行确认”传送原因7激活确认。 e. 操作完成后子站通过突发上送该开关的新状态。直接执行模式主站发送的命令中直接带“执行”标志子站收到后直接执行并回复。安全性较低较少使用。3.3 链路维护与超时机制通信链路不会永远顺畅104规约设计了一套健壮的维护和超时机制t0, t1, t2, t3 超时参数这是调试中必须关注的参数通常在子站侧配置。t1发送超时发送一个I帧后等待对方确认的最长时间。超过t1未收到确认则断开TCP连接。典型值15秒。t2无数据确认超时收到I帧后如果暂时没有数据要发必须在t2时间内发一个S帧确认。典型值10秒。t3链路测试间隔当链路长时间空闲时每隔t3时间发送一个TESTFRU格式作为心跳。典型值20秒。k, w 窗口参数w接收窗口最多能接收多少个未被确认的I帧。k发送窗口最多能发送多少个未被确认的I帧。 当发送了k个I帧都未收到确认发送方就会停止发送等待确认防止数据淹没接收方。典型的k12, w8。流程中的常见坑点主站收不到数据检查TCP连接是否成功、STARTDT握手是否完成、总召唤是否成功发起并结束。遥控失败检查“选择-执行”流程每一步的传送原因是否正确子站回复的确认帧中信息体是否与主站命令一致。很多时候失败是因为子站数据库里该点的“遥控允许”标志未设置。通信时断时续重点检查t1, t2, t3超时参数设置是否匹配。比如主站处理慢超过t2才回复S帧子站就可能认为超时而断链。4. 传送原因Cause深度解析读懂数据的“潜台词”传送原因Cause of Transmission是IEC104协议中极具智慧的设计它让一个冰冷的数据包有了“上下文”和“意图”。不理解传送原因就像听人说话听不懂语气很容易误解。根据网络热词我们来深入剖析所有Cause类型及其应用场景。传送原因占1-2个字节在标准中通常使用1字节0-255。最高位bit7通常用于表示是否由网络应用层如子站本身产生0还是由其他原因产生1如当地命令。我们主要关注低7位0-127的标准定义。以下是一些最核心的类型1. 周期性/背景扫描类 (1-2)1周期、循环。用于定时上送的慢变化数据如某些统计值。2背景扫描。主站后台召唤非实时数据时使用。为什么重要它们将周期性数据和事件数据区分开。主站处理时对原因1的数据可能采用不同的更新策略如平滑滤波而对原因3的数据则需要立即告警。2. 突发与事件类 (3-4)3突发自发。这是最重要的原因之一。表示因为设备状态或测量值发生了一个变化而主动上报。开关变位、测量值越限、保护动作信号都使用这个原因。它代表了最高的实时性。4初始化。子站重启或总召唤后重新初始化数据上送。实操心得很多子站在上送变位信号时会连续发两帧第一帧原因3第二帧原因3但品质描述字的“重复”位置1。主站需要正确处理这种“重复”帧避免重复告警。3. 请求与响应类 (5-8, 20)5被请求。直接响应主站的召唤命令如总召唤、组召唤、站召唤而发送的数据。20响应站召唤。专用于响应“站召唤”类型标识103命令。对比分析原因5和原因20都是响应召唤但“站召唤”通常用于召唤一个站的所有数据而组召唤或总召唤范围不同。在调试时如果主站发了召唤但收不到数据要检查子站回复的数据其传送原因是否正确。如果子站错误地用原因3突发回复召唤数据主站可能无法正确归类和处理这些数据。4. 命令激活与确认类 (6-10, 44-47)6激活。主站下发遥控、设点、时钟同步等命令时的“发起”动作。7激活确认。子站正确接收并准备执行“激活”命令时的确认。8停止激活。主站取消一个尚未执行的命令如遥控撤销。9停止激活确认。子站确认“停止激活”。10激活终止。命令执行完毕或失败如超时时发送。44未知的类型标识。子站收到无法识别的命令类型时回复。45未知的传送原因。子站收到无法识别的传送原因时回复。46未知的公共地址。地址错误时回复。47未知的信息体地址。点号不存在时回复。命令流程的精髓遥控过程6-7-6-7-10完美体现了工业控制对安全性和确定性的要求。每一步都必须得到明确确认才能进行下一步防止误动。原因44-47是宝贵的调试信息。当主站收到这些回复就能快速定位命令失败的具体原因是指令格式错、原因错、站址错还是点号错。5. 文件传输类 (13-19)用于传输故障录波文件、程序文件等大块数据。涉及目录操作、文件传输的激活、确认、中止等。在故障分析等高级应用中会用到。如何利用Cause排查问题假设一个遥控操作失败抓取通信报文主站发类型45原因6激活- 正常。子站回类型45原因7激活确认- 正常选择成功。主站发类型45原因6激活- 正常执行命令。子站回类型45原因47未知的信息体地址-问题定位子站认为主站下发的点号不存在于它的数据库中。检查主、子双方对该遥控点的地址定义是否一致。5. 调试实战从报文抓取到问题定位的完整链路理论再扎实最终也要落到调试上。现场调试IEC104一台电脑、一个抓包工具如Wireshark和一份协议文档就是你的全部武器。下面我以一个典型的“主站收不到子站遥测数据”的故障为例展示完整的排查链路。5.1 第一步基础连通性检查现象主站软件显示与子站通信中断或未初始化。操作在连接子站的网段用笔记本电脑ping一下子站的IP地址。不通检查网线、交换机、子站网口灯、IP配置。使用telnet 子站IP 2404命令测试TCP 2404端口是否开放。如果连接被拒绝说明子站的104服务未运行或防火墙拦截。如果ping通但telnet不通大概率是子站程序问题或防火墙规则。需要登录子站设备检查。经验技巧很多嵌入式设备的104服务启动较慢设备上电后可能需要等待1-2分钟服务才完全就绪。别急着下结论。5.2 第二步抓取初始握手报文现象TCP能连接但主站显示“链路未激活”或“无数据”。操作在主站侧或网络镜像口用Wireshark开始抓包过滤条件设为tcp.port 2404。重启主站对该子站的通信进程或者手动连接。观察抓到的包。你应该能看到清晰的流程TCP三次握手。主站 - 子站U(STARTDT act)。子站 - 主站U(STARTDT con)。如果缺少这一步后续所有I帧都无效。主站 - 子站类型100原因6总召唤激活。子站 - 主站类型100原因7总召唤确认。问题定位如果看不到STARTDT主站程序可能配置错误未发送启动命令。检查主站通信配置中“启动后发送STARTDT”选项是否勾选。如果子站没回STARTDT con子站程序可能存在问题或者其当前模式不允许数据传输如处于维护状态。如果总召唤没发或没确认主站可能未配置总召唤或总召唤周期设置过长。子站可能未正确响应总召唤。5.3 第三步分析业务数据流与窗口机制现象握手和总召唤都正常但主站只收到一小部分数据后就停滞了或者数据更新非常慢。操作在Wireshark中仔细观察I帧的控制域。找到发送序号N(S)和接收序号N(R)。计算“未确认帧数”。例如子站发送的最后一个I帧N(S)15而主站最近回复的S帧或I帧中的N(R)10那么就有5个帧序号10,11,12,13,14未被确认。检查主站回复的S帧或I帧的频率。如果子站发了大量数据主站却很久才回复一个S帧可能导致子站的发送窗口k被占满而停止发送。问题定位主站处理能力不足这是最常见的原因。主站后台处理报文、写入数据库的速度跟不上子站发送的速度导致确认帧回复延迟。需要优化主站性能或调整子站发送节奏如增加发送间隔。窗口参数不匹配检查子站配置的发送窗口k值。如果k1那么子站每发一帧都必须等主站确认后才能发下一帧效率极低。通常建议k8或12。同时检查主站的接收窗口w应大于等于子站的k。网络延迟或丢包在Wireshark中查看是否有TCP重传。网络不稳定会导致确认帧丢失子站因超时t1而断链。5.4 第四步解码ASDU与核对点表现象主站能收到数据但数据显示错误比如开关状态反了、测量值不对、或者点号错乱。操作在Wireshark中右键选中一个104报文 - “解码为...” - 选择“IEC 60870-5-104” 可能需要安装或配置Wireshark的104解析插件。展开解码详情逐层查看APCI和ASDU。重点关注类型标识确认是遥信(1)、遥测(9)还是其他。传送原因是突发(3)还是被请求(5)是否符合预期信息体地址将其从16进制转换为10进制。例如0x000001是10x000065是101。信息体元素对于遥信看最低位是0还是1。对于遥测规一化值需要理解其编码。标准中规一化值 实际值 / 标度因子 偏移量。但更常见的是直接采用短浮点数IEEE 754。在Wireshark解码中它会直接显示转换后的十进制值。拿出你的点表数据库对照表找到地址对应的点号描述。核对Wireshark中解码出的地址、值、品质描述是否与点表定义和实际设备状态一致。问题定位地址映射错误这是“经典坑”。子站上送的地址是101但主站数据库里把101映射成了“102开关”。必须保证两端点表完全一致。制作点表时建议使用Excel并利用16进制与10进制转换函数反复核对。数据格式误解最大的坑在于遥测值。早期设备可能使用“规一化值”一个整数需要换算现代设备基本都用“短浮点”。主站解析模块必须与子站发送的格式匹配。如果子站发浮点主站按整数解析数值会完全错误。务必在调试前与设备厂家确认数据格式。品质描述字忽略信息体元素中附带2个字节的品质描述如无效、溢出、被取代、封锁等。如果主站程序没有处理这些标志当一个值被标记为“无效”时主站可能仍然显示上一个有效值造成误导。5.5 第五步高级问题与稳定性调优当基本通信搞定后还会遇到一些更深层次的问题问题子站频繁断链重连。排查检查超时参数t1, t2, t3。如果网络延迟大如经过多个路由器需要适当调大t1和t2例如t130秒t215秒。确保主站能及时回复S帧确认。经验在广域网或无线网络如4G上使用104时网络抖动是常态。除了调大超时还可以减小发送窗口k例如k2或3并增加子站发送间隔降低对实时确认的依赖。问题遥控命令总是超时失败。排查抓包确认完整的“选择-确认-执行-确认”流程每一步的传送原因是否正确。检查子站回复的“激活确认”帧中信息体地址和命令状态是否与主站下发的一致。最关键登录子站设备查看该遥控点的属性设置。是否存在“遥控压板”未投入“同期检定”条件不满足“五防逻辑”闭锁这些都是在协议层之上的应用逻辑闭锁协议报文本身是正确的但子站内部逻辑拒绝执行。经验遥控失败十有八九问题不在协议通信而在子站的本地逻辑闭锁。需要和设备维护人员一起检查。问题如何模拟测试工具使用专业的104仿真软件如KEPServerEX的IEC Driver配合仿真插件或一些开源/商业的104测试工具可以模拟主站或子站。自建简易测试如果你懂编程用Python的socket库按照104帧格式拼接报文可以模拟发送U帧建立链路发送I帧模拟数据。这对于理解协议底层和验证主站基本接收功能非常有效。调试IEC104本质上是一个“证据链”分析的过程。Wireshark抓包提供了不可辩驳的证据。你的任务就是像侦探一样对照协议规范解读每一个报文找出逻辑断裂或不符合预期的那一环。这个过程很枯燥但当你定位到那个错误的字节并修复它看到数据如流水般稳定上送时那种成就感是无与伦比的。