【问题标题】:Best way to stop multiple RT Timed Loops simultaneously?同时停止多个 RT 定时循环的最佳方法是什么?
【发布时间】:2015-07-08 16:10:11
【问题描述】:

背景

我有一个实时应用程序RT Main,它有多个高优先级定时循环,运行一些模拟代码并使用 RT FIFO 与与外部程序对话的低优先级通信循环进行通信。我还有一个监控 VI,DT Main,在非实时桌面上运行,我用它来启动和停止实时模拟、加载参数文件等。

目前我通过网络共享变量将Stop 按钮从DT Main 传递到RT Main。我想知道的是:如何使用它来同时(接近)同时停止RT Main 上的所有循环?

我知道我可以在我的定时循环中使用启用 FIFO 的网络共享变量,但我担心从同一个 FIFO 读取多个循环时,我只会停止其中的一两个,然后 FIFO 会被清除并且其他循环不会停止。

当前计划

  1. 使用网络共享的Stop 按钮变量停止低优先级通信循环。
  2. 当此循环停止使用RT FIFO Delete VI 并将force destroy? 输入设置为True 时,删除我的所有RT FIFO。
  3. 让高优先级循环在下次尝试读取其(现已销毁的)FIFO 时自行关闭,这可能会导致错误。

这在下面的一个精简示例中得到了说明。

问题

我有两个问题:这行得通吗?不管这是否有效,在 LabVIEW 的实时应用程序中停止多个高优先级定时循环的“正确”方法是什么?

我不知道RT FIFO ReadRT FIFO Write VI 在尝试读取/写入不存在的 FIFO 时是否会引发错误。有一个RT FIFO error code -2206 "RT FIFO does not exist" 我假设在这些情况下会被抛出,但我现在无法测试它(还没有硬件可以运行它),所以我无法验证。

作为记录,到目前为止,我发现 NI LabVIEW for CompactRIO Developer's Guide 非常有帮助,但似乎没有足够详细的信息来回答我的问题。

谢谢!

更新

我能够测试代码并验证我可以以这种方式停止多个定时循环,但我仍然有兴趣了解您的最佳方法是什么来关闭远程 RT VI按下桌面 VI 上的一个按钮即可实现多个循环。

【问题讨论】:

    标签: while-loop real-time labview fifo


    【解决方案1】:

    定时循环的关注点在于保持一切都是确定性的。

    确定性通信的另一个选项是使用启用 RT FIFO 的共享变量。如果将其设置为单元素 FIFO,它仍然可以像普通变量一样工作。

    我相信这也可以直接作为网络变量而没有任何问题,或者有时我喜欢将内部通信保持在内部并有另一个循环将读取网络变量并将其写入内部变量以减少主机之间的耦合和 RT 目标实现。

    这允许在软件中使用更明确的停止功能,从而提高灵活性和可读性。示例见图片:

    【讨论】:

    • 谢谢!我对此感到担忧,但我可能只是误解了一些东西。每次循环从启用 FIFO 的共享变量中读取时,它都会从该变量中删除最旧的元素,对吗?那么我是否需要不断地将True 值写入Stop 共享变量,以便共享它的所有循环都有机会读取它?我觉得我过去在将循环与共享变量同步时遇到了一些问题,但我可能没有启用 FIFO。
    • 另外,我已经有了 FIFO。不过,我确实喜欢更明确地停止循环,这样维护代码的人就不会对神奇的关闭过程感到困惑。
    • 当共享变量的 RT FIFO 设置设置为单个元素时,它不再像 FIFO 一样工作,而是像变量一样,因此您可以写入一次,每个地方都会读取它。正如您所说,您已经拥有 FIFO,所以这是额外的,但它更明确,因此我倾向于更喜欢它,但在功能上两者都可以工作。
    【解决方案2】:

    示例代码用于使用已损坏 FIFO 中的错误同时关闭多个定时循环。我可以使用如下所示的 VI 进行验证。

    我仍然想听听您的最佳解决方案,通过桌面 VI 上的单个停止按钮停止具有多个循环的 RT VI。

    【讨论】:

      【解决方案3】:

      这将是做到这一点的最佳方式,并且是跨平台的Producer-Consumer pattern。我的一个建议是不要在销毁 FIFO 时使用Force Destroy 选项。最好单独跟踪 FIFO,并确保正确销毁所有实例,而不是原子地消除对 FIFO 的所有引用。从我在您的应用程序中可以看到,您没有创建命名的 FIFO,因此不需要原子地销毁 FIFO 的所有实例。

      干杯,马特

      【讨论】:

      • 谢谢,马特。我实际上是在实际应用程序中创建命名 FIFO。我只是不认为这对于说明性示例来说太重要了。鉴于命名的 FIFO,force destroy? 选项仍然是我的最佳选择吗?
      • 当 FIFO 访问失败时,只要您的循环根据需要进行清理就足够了。
      猜你喜欢
      • 1970-01-01
      • 2020-12-06
      • 2012-01-05
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多