西门子S7协议介绍 您所在的位置:网站首页 莲藕种植技术和管理 西门子S7协议介绍

西门子S7协议介绍

2023-12-06 10:44| 来源: 网络整理| 查看: 265

据我所知,S7协议没有公开的文档,由于没有官方文件,S7协议不存在官方术语。但是有几个开源的项目可以帮助我们处理S7。

Davide Nardella创建了一个非常棒的开源通信库Snap7,它实现了基本的通信场景。该库提供了S7协议基本结构的大量文档。另一个伟大的项目 S7 Wireshark dissector。Wireshark抓包软件的一个插件,它涵盖了协议的大部分内容,其源代码包含一个冗长的协议常量列表。我了解了一个新的、积极开发的开源项目plc4x。该项目提供多种工业协议的实现,包括S7协议。 1. 西门子通信方案

S7 protocol指的是以太网S7通信,主要用于将PLC连接到(I)PC工作站(PG/PC-PLC通信)。这不应与西门子设备使用的不同现场总线协议混淆,例如MPI、Profibus、IE和Profinet(这是一种基于以太网的协议,用于将PLC连接到IO模块,而不是设备的管理协议)

大多数情况下,西门子通信遵循传统的主从模式(master-slave)或者CS模式(client-server )。其中PC(master/client)将S7请求发送到现场设备(slave/server)。这些请求用于从设备查询或向设备发送数据或发出某些命令。当PLC作为通信主站时(master)有一些例外,通过FB14/FB15设备可以向其他设备发起GET和PUT请求。

在S400系列中,实现了所谓的循环数据I/O功能,这类似于传统的发布者 - 订阅模型。PC可以订阅某些事件,而不是PLC 定期推送所请求的数据送到网络。还有一个合作伙伴(Partner )或点对点模型,当一个活动的合作伙伴请求连接并调用阻止发送(Block Send),与此同时被动合作伙伴调用阻止接收(Block Receive)方法。

有关S7通信概述的更多信息,请参阅西门子Simatic Net和Snap7文档。 

2. S7 PDU

S7协议TCP/IP实现依赖于面向块的ISO传输服务,S7协议包含在TPKT和ISO-COTP协议中,允许PDU(协议数据单元)通过TCP承载。ISO overTCP通信定义在RFC1006中,ISO-COTP定义在RFC2126其是基于ISO 8073协议(RFC905)。该结构如下图。

S7协议是面向功能/命令的,这意味着传输由S7请求和适当的应答组成(极少数例外)。在连接建立期间协商 传输的数量和PDU的最大长度。

S7 PDU 由三个主要部分组成:

头(Header):包含长度信息, PDU reference ,message type 常量参数(Parameters):内容和结构根据PDU的Message Type和Function Code而有很大差异数据(Data):它是一个可选字段,用于携带任何数据,例如内存值、快信息、固件数据等。 2.1 头(Header)

报文长度为10-12个字节,应答报文包含两个额外的错误代码字节。除此之外,标头格式在所有PDU中是一致的。

字段:

Protocol ID: 协议ID,协议常量,始终设置为0x32Message Type: 消息的一般类型(有时称为ROSCTR类型),消息的其余部分在很大程度上取决于Message Type和功能代码: 0x01- Job Request:主站发送的请求(例如读/写存储器,读/写块,启动/停止设备,通信设置) 0x02- Ack:从站发送的简单确认没有数据字段(从未见过它由S300 / S400设备发送) 0x03- Ack-Data:带有可选数据字段的应答,包含对Job Reques的回复 0x07- Userdata:原始协议的扩展,参数字段包含请求/响应Id(用于编程/调试,SZL读取,安全功能,时间设置,循环读取...) Reserved: 保留字段,始终设置为0x0000(但可能忽略)PDU reference: 主站(master)生成,每次新传输递增,用于链接对其请求的响应,Little-Endian(注意:这是WinCC,Step7和其他西门子程序的行为,它可能是随机的生成后,PLC只将其复制到回复中)Parameter Length: 参数字段的长度,Big-EndianData Length: 数据字段的长度,Big-Endian(Error class):  仅存在于Ack-Data报文中,可能的错误常量查看协议常量(Error code):  仅出现在Ack-Data报文中,可能的错误常量查看协议常量

 

2.2 参数(Parameters)

 通常以Function Code  开头 占一个字节,

0x00 - Cpu Services0xF0 - Setup Communication0x04 - ReadVar0x05 - WriteVar0x1A - Request Download0x1B - Download Block0x1C - Download End0x1D - Start Upload0x1E - Upload0x1F - End Upload0x28 - PLC Control0x29 - PLC Stop

后面的报文因Function Code和Message Type而有很大差异 

2.3 数据(Data):

 

 

3. Job Request 和 Ack-Data报文

 

消息的其余部分在很大程度上取决于Message Type和Function Code

这里分析仅针对Message Type为:

0x01- Job Request:主站发送的请求(读/写存储器,读/写块,启动/停止设备,通信设置)0x03- Ack-Data:带有可选数据字段的应答,包含对Job Reques的回复

通常每个Job Request求都会产生一个 Ack-Data数据回复。

Job Reques和Ack-Data报文的参数(Parameters)都是以功能代码开头,其余字段的结构取决于此值。

3.1 配置通信(Setup Communication)[0xF0]

此消息对(Job Reques和Ack-Data)在每个会话开始时发送,然后才能交换其他任何消息。它用于协商Ack queues 的大小和max PDU length,双方都声明其支持的值。Ack queues 的长度决定了可以在没有应答的情况下同时启动的并行Job Reques的数量。

max PDU length和Ack queues字段都是 Big-Endian。

参数结构如下图所示:

字段:

    Function code:功能代码,Setup Communication为 0xf0    reserverd:保留字段,默认为0x00    Max AmQ Caller :Ack队列的大小(主叫)  通常 0x01    Max AmQ Callee:Ack队列的大小(被叫)  通常 0x01    PDU length: PDU长度。

 

3.2 S7认证和保护(Authentication and Protection)

在配置CPU期间,可以设置三种保护模式。

没有保护(No protection):正如人们所期望的那样,不需要身份验证。写保护(Write protection):对于某些数据写入和配置更改操作,需要进行身份验证。读/写保护(Read/Write protection):就像前一个一样,但某些读操作也需要验证。

必须注意的是,即使启用了读/写保护,也会允许某些操作,例如读取SZL列表、读\写M区。其他操作(如读取或写入对象/功能/数据块)返回权限错误。

有两个与CPU关联的保护级别,他们是:分配保护级别和实际保护级别。

分配保护级别是配置期间设置的保护级别而实际的保护级别是适用于通信会话的当前保护级别。

在正常操作期间,在配置通讯(Setup Communication)之后,客户端通过查询SZL reads(SZL ID: 0x0132 SZL Index: 0x0004)得到读写权限,查询实际保护级别和分配保护级别。

如果需要认证的密码以用户数据消息被发送到设备,这会降低有效的保护水平。

认为这至少提供了一点点安全性之前,但它不是。密码是六个字节,几乎以明文形式发送(与常量进行异或并移位)。它是可重放的,可以强制执行。该协议还不提供完整性或机密性保护,可以进行消息注入和修改。S7安全性的一般经验法则是,如果您可以ping设备,则可以拥有它。

这里必须注意的是,S7-1200/1500系列设备使用略有不同的方法,保护级别处理稍有不同,发送的密码明显更长(实际上是密码的哈希),但它仍然是不变的,可重放。

3.3 读/写变量(Read/Write Variable)[0x04,0x05]

数据读写操作通过指定变量的Memory Area、address (offset)、Size or Type来操作。在进入协议细节之前,先简要介绍一下S7寻址模型。

如前所述,通过指定地址来访问变量,该地址由三个主要属性组成。

Memory Area:

0x83 - Merker[M]: 任意标记变量或标志寄存器驻留在这里。0x84 - Data Block[DB]: DB区域是存储设备不同功能所需数据的最常见位置,这些数据块编号为地址的一部分。0x81 - Input[I]: 数字和模拟输入模块值,映射到存储器。0x82 - Output[Q]: 类似的存储器映射输出。0x1c - Counter[C]: PLC程序使用的不同计数器的值。0x1d - Timer[T]: PLC程序使用的不同定时器的值。

还有其他不太常见的存储区域(例如本地数据[L]和外设访问[P]等)。

变量的type 决定了它的长度以及应该如何解析它。

DataType:

0x01 - BIT:一个无符号的bit0x02 - BYTE:一个8位的数字0x03 - CHAR:一个字符0x04 - WORD:两个字节宽的无符号整数0x05 - INT:两个字节宽的有符号整数。0x06 - DWORD:四字节宽的无符号整数0x07 - DINT:四字节宽的有符号整数0x08 - REAL:四个字节宽的IEEE浮点数0x1c - COUNTER:PLC程序计数器使用的计数器类型

示例:

变量的示例地址是DB123X 2.1,

它访问DB块123的第三个Byte的第二个Bit。

 

在这个简短的介绍之后,回到协议的变量读/写的实现。S7协议支持使用不同的寻址模式在单个消息中查询多个变量读/写。主要有三种模式:

any-type:这是默认的寻址模式,用于查询任意变量。为每个寻址变量指定所有三个参数(Area,offset,dataType)db-type:这是专门用于解决DB区域变量的特殊模式,它比any-type地址更紧凑symbolic-addressing: S7-1200/1500系列设备使用此模式,允许使用预定义的符号名称寻址某些变量。此处不会详细介绍此模式

对于每种寻址模式,参数(Parameters)头的结构方式相同:

Function Code: 读取的常量值0x04或写入作业和回复的0x05Item Count: Request Item结构的数量 Request Item:此结构用于地址实际变量,其长度和字段取决于所使用的寻址模式。这些项仅存在于Job request中,并且从相应的Ack Data发出,而不管寻址模式是什么,也不管它是读请求还是写请求。

S7 PDU 的数据(Data) 部分根据消息的类型(read/write)和方向(Job/Ack Data)而变化:

Read Request:该Data 部分是空的。Read Response:Ack-Data报文的Data 部分由Data Item结构组成,每个结构对应于原始请求中存在的每个 Request Items。这些项包含读变量的实际值,格式取决于寻址模式。 Write Request:包含与Read Response类似的Data Item,每个Data Item对应于Parameter header中的每个Request Items。类似地,它们包含要写入从属设备的变量值。Write Response:Ack Data消息的Data分仅包含原始Write Request中每个Request Items的一个单字节错误代码。有关错误代码值,请参阅协议常量

总之,Request Item总是包含变量的描述,并且可以在Job request中发送多个变量,而Data Item包含所描述变量的实际值。Data Item结构必须以偶数字节开始,因此如果它们的长度是奇数,并且有一个后续的Data Item,则用零字节填充它们。

3.3.1 any-type 寻址模式 的  Item 结构

下图显示了Request Item和Data Item结构:

Request Item的字段:

Specification Type: 该字段确定结构的主要类型,对于读/写消息,它总是具有值0x12,代表变量规范。Length: 此项目其余部分的长度。Syntax ID:此字段确定项结构其余部分的寻址模式和格式。any-type 模式 常量是0x10 。Variable Type: 用于确定变量的类型和长度(使用常用的S7类型,如REAL,BIT,BYTE,WORD,DWORD,COUNTER等)。Count:可以用单个item 结构选择整个相似变量数组。这些变量必须具有相同的类型,并且必须在内存中连续,并且count字段确定此数组的大小。对于单变量读或写,它设置为1。 DB Number:DB快的地址,如果该区域未设置为DB,则忽略该数据库(参见下一个字段)。 Area: 选择地址变量的memory area 。见协议常量的内存区域的常数。Address: 包含选定memory area中地址变量的offset。基本上,地址被转换成位offset,并按big endian字节顺序编码在3个Byte上。实际上,由于地址空间小于5 Bit,因此从不使用最高有效位。例如,DBX40.3将是0x000143,即40*8+3。

Data Item字段

 Error Code:操作的返回值,0xff信号成功。在“Write Request消息中,此字段始终设置为0。 Variable Type and Count: 与 Request Item中的相同。 Data:此字段包含已寻址变量的实际值,其大小为 len(variable) * count。

 

3.3.2 db-type 寻址模式 的  Item 结构

下图显示了Reques Itemt和Data Item结构

Request Item字段:

Specification Type:与any-type寻址模式相同。  常量:0x12Length: 此项目其余部分的长度。Syntax ID: 确定寻址模式,db-type的常量值为: 0xb0 。Number of Subitems:  后面Subitem的数量。Subitem:

            Size: 指定从选定地址读取或写入的Byte数量。

            DB Number: 地址变量所在的DB快。

            Address: 指定DB快的  byte 偏移量。

 

Data Item的字段:

Error Code:操作的返回值,0xff 表示成功。Variable Type: 始终设置为0x09(八进制字符串)。Length: 剩余子Subresponse 数据的长度。Subresponse:

        Error Code: 与Subitem请求关联的返回值。

        Data:要读取或写入的实际数据,解析数据需要相应的Subitem。

 

3.4  Block Up/Download [0x1a-1f]

 

在西门子的术语中,下载(download )是主设备向从设备发送块数据,上传(upload )是另一个方向。在西门子设备上,程序代码和大部分程序数据存储在块中,这些块有自己的头和编码格式,这里不详细讨论。从协议的角度来看,它们是需要传输的二进制blob(对于感兴趣的读者,snap7源提供了有关块头及其编码的信息)。

西门子设备认可七种不同类型的块:

OB:组织块,存储主程序。(s)DB :(系统)数据块,存储PLC程序所需的数据。(s)FC : (系统)功能,无状态功能(没有自己的内存),可以从其他程序调用。(s)FB : (系统)功能块,有状态的功能,通常有关联的(S)DB。

 西门子文档中详细描述了这些模块的用途。

这些块在uploda/download请求中使用特殊的ASCII文件名进行寻址。此文件名的结构如下:

File Identifier: [1char]   据我所知,这个值总是'_'Block Type: [2char]   确定块类型,有关具体值,请参见协议常量。Block Number: [5char]  十进制格式的给定块的编号。Destination File System: [1char]  对于主动文件系统,此字段的值可以为   'A',对于被动文件系统,则为 'P'。复制到活动文件系统的块会立即链接起来,这意味着一旦PLC执行恢复,这些块就会生效。另一方面,需要首先激活复制到被动文件系统的块。

示例: 

文件名是 _0800001P,用于将OB 1复制到被动文件系统或从被动文件系统复制OB1。

Let me make a quick note on block encoding and content protection. There are two measures in place to protect the content of programs and data on the devcies and allow the distribution of program libraries. The first one is called know-how protection, which if set prevents STEP7 or TIA showing the actual content of the block. Unfortunately, this is trivial to bypass, as it is just two bits set in the header of the blocks and can easily be cleared. The other protection measure is block “encryption”, which in reality is just an obfuscation with linear transformations (bytewise xoring and rotating with constants), again should be trivial to bypass. So do not rely on these “security” mechanisms to protect your know-how. Otherwise the data blocks contain the raw, initialized image of the memory. Program blocks contain the MC7 (Machine Code 7) binary instructions. 

 让我简要说明一下块编码和内容保护。有两种措施可以保护设备上程序和数据的内容,并允许分发程序库。第一种称为专有技术保护,如果设置了该保护,则会阻止STEP7或TIA显示块的实际内容。不幸的是,这是琐碎的绕过,因为它只是两位设置在头的块,可以很容易地清除。另一种保护措施是块“加密”,它实际上只是一种线性变换的模糊处理(字节xoring和常数旋转),同样应该是可以忽略的。所以不要依赖这些“安全”机制来保护你的技术。除此以外,数据块包含内存的原始初始化镜像。程序块包含MC7(机器代码7)二进制指令。

上传和下载块涉及3-3种不同类型的消息对。下面列出了相关的功能代码:

Request Download  - 0x1aDownload Block  - 0x1bDownload Ended - 0x1cStart Upload - 0x1dUpload Block  - 0x1eEnd Upload  - 0x1f

这些消息的结构非常简单,但是消息序列(特别是下载)需要一些解释。

3.4.1 Upload Block [0x1a]

上传块序列非常直观,如下所示:

在Ack Data - Start Upload消息中,slave告知块的长度,然后主设备继续发送Job - Upload Block消息,直到接收到所有字节。最后,它使用Job - End Upload消息关闭上传序列。块的实际数据由从Ack Data - Upload Block消息中发送。

Job - Start Upload  参数头:

Function Code: [1b]  0x1d用于Start Upload.。Function Status: [1b] 仅用于Upload message,如果要发送更多数据,则设置为0x01。 Unknown: [2b]  常量 0x0000。Session ID: [4b] 与每个上传序列相关联的唯一ID,它在Ack Data - Start Upload消息中设置。Filename Length: [1b] 以下文件名的长度。Filename:标识块的文件名。

Ack Data - Start Upload   参数头:

Function Code: [1b]   0x1d用于Start Upload。Function Status: [1b] 与上述相同。Unknown: [2b] 常量0x0100。Session ID: [4b]  此处设置Session ID ,连续消息使用相同的值。Length String Length: [1b] 以下Block Length String的长度。Length String:编码为ASCII C字符串的块的十进制长度(不要问我为什么......)。

Job - Upload  参数头:

包含如上所述的Function Code(0x1e)、Function Status、Unknown(0x0000)和Session ID字段。

Ack Data - Upload   Parameter and Data Parts:

Function Code: [1b]  0x1e用于Upload   。Function Status: [1b] 如果要发送更多数据,则设置为0x01。Data :

                Length: [2b] Block Data的长度。

                Unknown: [2b] 总是  0x00fb。

                Block Data:上传数据块的一部分。

Job - End Upload  Parameter Header:

包含Function Code(0x1f),Function Status,Unknown(0x0000)和Session ID字段,如上所述。

Ack Data - End Upload  Parameter Header:

 只包含Function Code(0x1f) 3.4.2 Download Block [0x1b]

 Upload 和Download 的关键区别在于,在下载过程中,通信的方向发生了变化,slave变成了master(有点像)。在初始Request Download exchange之后,slave发送 Job messages,而master回复Ack Data,这是“slave only replies”规则的唯一例外。发送完所有字节后,master(原始)发送 Download Ended Job以关闭下载会话。请参见下面的序列图。

实际消息的结构与上传消息非常相似,所以这里只介绍差异。

 Job - Request Download 消息中包含了两个附加字段,下载块的Block Length 和 Payload Length(不包含块头的长度)​​​​​​​。这两个字段都是编码为ASCII字符串的十进制数字。响应 Ack Data - Request Download 仅包含Function Code。

另一个显着的区别是,虽然Session ID字段存在,但不使用(仍为0x00000000)而是在每个 Job - Download Block传输文件名。其余消息的结构与前面讨论的相同。

 

3.5  PLC Control [0x28]

 

(尝试使用s7comm.param.func==0x28 wireshark筛选器查找PLC控制消息) 

PLC控制消息用于在从属设备上执行不同的命令,以修改其执行/内存状态。此类命令用于启动或停止PLC控制程序的执行,激活或删除设备上的程序块,或将其配置保存到永久存储器中。这些消息的结构相当简单,将在不讨论确切细节的情况下对其进行解释。

ob - PLC Control消息由两个主要部分组成,即被调用方法的ASCII名称和参数(也被编码为ASCII字符串)。方法名的结构与块传输部分中引入的文件名类似。参数取决于方法类型,可以将其视为方法类型的参数。 Ack Data消息仅包含PLC Control功能代码。

一些示例函数名称及其相关参数:

_INSE:激活设备上下载的块,参数是块的名称(例如OB1)。_DELE:从设备的文件系统中删除一个块,该参数也是块的名称。 P_PROGRAM:设置设备的运行状态(启动,停止,mem重置)。它在没有参数的情况下发送以启动设备,但是停止plc程序使用不同的功能代码(参见下一节)。_GARB:压缩PLC内存。_MODU:将ram复制到rom,该参数包含文件系统标识符(A/E/P)。 3.6 PLC Stop[0x29]

所述PLC Stop消息是基本相同的PLC Control 消息。唯一的区别是消息中没有参数,并且例程部分始终设置为P_PROGRAM。不知道为什么它有单独的类型而不是使用参数来确定它是一个开始或停止消息。

 

4 结尾

嗯,这篇博文比我最初计划的要长得多,但我希望它对一些人有用。这可能是显而易见的,但S7协议不是一个设计良好的协议。它最初是为了简单地查询寄存器值而创建的,它做得还不错,但后来不断添加功能,直到它变成了这个怪物。它充满了不一致性和不必要的冗余,而且用户数据消息只会变得更糟。在尝试为协议编写解析器时,这些不规则和设计缺陷变得更加明显(而且令人讨厌)。

如果S7是一辆汽车,它可能会像这样:

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有