【问题标题】:Are CIP services for reading and writing PLC tags (on AB Logix 5000 controllers) atomic?用于读取和写入 PLC 标签(在 AB Logix 5000 控制器上)的 CIP 服务是原子的吗?
【发布时间】:2019-07-08 18:41:50
【问题描述】:

我正在关注有关使用 CIP 进行控制器数据访问的 Allen-Bradley 文档,特别是读取标签服务、写入标签服务以及有关读取/写入整个 UDT 的详细信息:https://literature.rockwellautomation.com/idc/groups/literature/documents/pm/1756-pm020_-en-p.pdf。我正在使用 EIP 库来执行读/写标签服务和多服务请求。

我想澄清的是读取或写入整个 UDT 是否是原子操作(使用手册中概述的方法在一个服务请求中执行读取/写入并了解元数据以解压缩它)?即,当整个成功读/写时,PLC 或软件端是否永远不会看到部分更新的 UDT 值?

一个相关的问题是:如果我想通过在一个多服务请求中发送多个读/写标签服务请求来读/写多个标签,我对这组标签的同步读/写有任何保证吗?我认为不是,但我似乎无法找到有关该主题的任何明确文档。特别是如果请求被分成多个 CIP 数据包。

【问题讨论】:

  • 你解决了这个问题吗?
  • 好的,谢谢。我刚刚发布了一个答案。我的问题可能还不清楚,但我更感兴趣的是从 PLC 的角度来看,读/写是否是原子的(即 PLC 看到的是一致的数据而不是部分更新的数据)。服务请求确实成功,但我发现它不会自动与 PLC 同步,因此如果数组/UDT 需要同步,我可以为此添加标志或互斥锁。再次感谢!

标签: plc


【解决方案1】:

我能够对此进行测试并确认读/写标签 CIP 服务对于单个 UDT 或数组来说不是原子的。我最初担心的是我是否可以安全地写入整个 UDT 或数组,并确保处理该数据的 PLC 将看到处于“写入前”或“写入后”状态的数据,而不是某些部分写入的状态。我执行了一些测试,从 CIP 写入标签服务写入一个 10 元素 DINT 数组。在 PLC 上,我执行同步复制 (CPS) 以将数组复制到另一个标签中,然后检查它以查看数据是否与被原子复制一致。我看到数据偶尔处于部分写入状态,这意味着写入标签服务与同步复制指令不同步。请注意,我使用单个 CIP 服务请求来写入数组,而不是每个元素的多个请求。这并不完全出乎意料,但很高兴知道这样任何从 CIP 服务读取/写入多个值的人都知道缺乏同步。如果需要,我可以添加自己的同步机制。

【讨论】:

  • 您是否使用了特定于 MSG 控制器的状态寄存器?还是一个计时器来确保所有数据在使用任何阵列/UDT 之前到达?要么???我只是想看看其他人是如何给这只猫剥皮的。
  • 我对 MSG 控制器不熟悉。在我的例子中,我使用了一个 Java 库来实现 EIP 服务,包括读/写标签服务。在 PLC 方面,我在程序中没有任何明确的指令来接收/发送数据,它只是更新了控制器范围的标签。因此,就我而言,如果我需要指示数据何时完全写入,我可以添加一个“就绪”标志,这样我就不会在部分写入状态下处理它。
【解决方案2】:

我们通常检查消息响应字段中的“常规状态”以确定 CIP 消息的成功(完成??)或失败。但是,如果 PLC 在使用任何数据之前接收整个数据包至关重要,我将添加某种类型的计时器逻辑,以确保在(自信地)使用数据之前(在启动消息之后)有足够的时间。懒惰的?是的。但它有效。

具体到您关于通过读/写服务的原子性的问题。一般的经验法则是不要依赖任何原子的消息数据(尤其是大数据包)。您必须等待服务请求的反馈/响应。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    在工作中,我们发现任何超过 DINT 的读/写(我们没有尝试更小的数据)绝对不是原子的。

    我们努力寻找一种方法来确定读取何时返回“撕裂”数据。我们最终发现,“撕裂”总是连续的。读/写值的第一部分是最新的,而下一部分不是。

    所以我们使用了一组标记值。我们要读取或写入的任何标签的开头都有一个 DINT,最后一个 DINT。我们会将第一个标记设置为一个值,然后更新标记的其余部分。然后我们将设置最后一个哨兵。我们使用单调递增的值和对哨兵的强制换行。

    在读取这样的标签时,我们会比较标记值。如果它们相同,那么我们读得很好。如果不是,我们再读一遍。

    sentinel X header
    <data>
    sentinel X footer
    

    如果我们看到的数据在传输过程中被“撕裂”:

    sentinel X header
    <data>
    sentinel X-1 footer
    

    我对此进行了相当多的测试(我创建并维护了一个用于与 Allen-Bradley PLC 通信的 C 库),并且我能够使用两个 DINT 的简单数组来显示“撕裂”。我没有尝试较小值的数组。

    根据我们的经验,UDT 与 DINT 数组没有什么不同。如果该值大于 DINT,则可以针对程序扫描进行部分读取或写入。

    【讨论】:

      猜你喜欢
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 2016-06-13
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      相关资源
      最近更新 更多