Snap7-Server 既不是一种真实PLC,也不是从PLC收集数据并呈现结果的程序。
Snap7-Server 就像通信处理器 (CP) 一样,接受外部客户端的 S7 连接,并回复其请求。
与 CP 共享资源的 CPU 一样,应用程序必须与服务器共享其资源(内存块)。
从 1.4.0 Snap7-Server 开始,可以在PG模式下工作。
Snap7-Server系统架构图:
· 程序分配一个内存块,对服务器说"这是您的 DB1"。每次客户端请求从/到 DB1 读取/写入一些字节时,服务器都会使用该块。
· 如果客户端请求访问不存在的块(即您未共享的块),服务器会回复未找到资源的错误,就像真正的 PLC 一样。
HMI看不到与实际 PLC 的任何区别。
仿真级别相当深:S7 管理器(或 TIA 门户)本身将您的应用程序视为 CPU 315-2PN/DP。
在线项目
模块信息
通讯信息
•每个客户端(Scada、hmi 面板、PLC 驱动程序)都会将服务器视为真正的 PLC。
Snap7-Server技术规格
Snap7-Server 是一个多客户端多线程S7通讯服务器。
接受连接后,将创建一个新的 S7 工作线程,该线程将在此时刻为该客户端提供服务。
当客户端断开连接时,S7 工作线程将销毁。
最多 1024 (*) 连接可以接受,但此值可以通过 Srv_SetParam() 进行更改。
目前没有黑名单/白名单机制来过滤连接,但在未来的版本中可以实施(取决于项目受众)。
当然,与 Simatic 管理器 的兼容性还不完整。
如前所说,服务器是 CP 模拟器,而不是 SoftPLC,即没有与 Simatic Manager 兼容的 MC7 程序进行编辑、上载或下载:业务逻辑(如果有)是您的应用程序。
S7 函数已实现(在当前版本中)
· 数据 I/O(也通过多变量读取/写入)
读/写DB、M、I区、Q区、T区和C区。
· 目录
列表DB块、DB块类型、DB块信息。
· 控制
运行/停止、压缩和复制 Ram 到 Rom。
· 日期和时间
获取/设置 PLC 日期和时间。
· 系统信息
读取 SZL
· 安全
获取/设置会话密码。
某些函数仅存在以模拟 PLC 存在,尤其是 :
(1)接受运行命令,后续获取状态命令将显示 CPU 处于运行状态,"停止"命令被接受,后续获取状态命令将显示 CPU 已停止。但它们对服务器没有实际影响。
压缩和复制RAM到ROM被接受,但(显然)他们什么都不做。
(2)获取日期和时间返回主机(服务器正在运行的 PC)日期和时间。接受设置日期和时间,但不修改主机日期和时间。
(3)接受任何密码。
未实现 S7 函数(在当前版本中)
· 上传/下载
· 编程功能
· 循环数据 I/O
控制流
每次服务器出现问题时:启动时、停止时、客户端连接/断开连接或发出请求时,都会创建一个"事件"。
该事件只是一个结构,定义为:
EvtTime 是事件的时间戳,即其创建的日期和时间。
EvtSender 是参与此事件的客户端的 IP。该格式为 32 位整数以节省内存,并可转换为字符串,如"192.168.0.34",使用套接字函数 inet_ntoa(每个 OS 套接字层都有)。
如果事件发送方是服务器本身(例如,在其启动时生成的事件),则此值为 0。
EvtCode 是事件代码,即其标识符(请参阅下面的列表)。
EvtRetCode 是事件结果,它与基础 S7 函数的结果(如果有)重合,否则为 0。
EvtParam1..EvtParam4 是其含义取决于上下文的参数。
在 snap_tcpsrv.h 和 s7_type.h 中,您将找到使用的所有常量。
Evt 代码列表
生成的事件遵循两种方式:事件队列和回调
事件队列是一个 FIFO 列表,包含关键部分,以确保事件一致性和线程安全。
每个 S7 辅助角色将其事件插入到队列中,您的应用程序使用 Srv_PickEvent() 提取这些事件。
如果队列已满,即不调用 Srv_PickEvent 或调用过慢,则不会插入该事件,并且只是丢弃。
在调用 Srv_ClearEvents() 时,队列将刷新。
回调
虽然,如前文所说,事件队列是为日志目的设计的,而回调机制是为控制目的而设计的。
回调都在 S7 辅助线程的线程中执行。在读取请求时调用第一个,然后再执行从 Snap7-Server 到客户端的数据传输。
最后,让我们看看完整的序列。
客户端请求从 DB4 读取一些数据。
工作流程:
调用读取回调(如果已分配),将读取坐标传递给它。
在读取回调中,我们可以根据需要修改 DB4。
从 DB4 获取数据。
将数据和作业结果发送到客户端。
检查日志筛选器并将事件插入到队列中。
检查回调筛选器,如果分配了回调,则调用将事件传递为参数的用户函数。
准备好接受进一步的客户端请求。
数据一致性
由于主应用程序与服务器共享其资源,因此需要采用同步方法来确保数据一致性。
当通过 Srv_注册区域()共享内存块时,服务器将创建一个块描述符。
此描述符包含
· 块号(仅当块是 DB 时才使用)。
· 块内存地址。
· 块大小。
· 关键部分对象引用。
只是该对象可确保数据一致性。
每次需要访问内存块时,S7 辅助角色都会"锁定"内存块,并在末尾解锁内存块。
为了提高性能,使用双缓冲方法:S7 辅助角色首先将数据接收到内部缓冲区,然后将内容复制到共享块中。
或者,在发送共享块之前,它将所需的数据复制到内部缓冲区。
只有复制操作锁定块。
如果需要数据一致性,则必须完成此规则。
为此,有两个函数: Srv_LockArea() 和 Srv_UnlockArea()。
您应该使用第一个来锁定内存块,而使用第二个来解锁内存块。
在长时间操作中,我建议您采用相同的双缓冲区策略:使用内部缓冲区,然后将数据传输到共享块中。此外,在块锁定时引发的异常将导致 S7 工作冻结。
注意
一致性的粒度是 PDU 大小。
多个服务器
在准备接收连接时,套接字必须绑定到 2 个参数:
(IP 地址、端口)。
建立了此规则,可以创建多个 Snap7-Server,但每个服务器都必须"启动"到不同的网络适配器上,因为侦听端口 (ISO TCP - 102) 无法更改。
运行两台服务器在两个不同的网段之间共享数据。
如果使用物理服务器,则建议的最大适配器为 16 个适配器。