5

允许 C 代码定期访问从单独的 Labview 程序生成的整数的瞬时值的最佳方法是什么?

我有控制科学实验并每 20 毫秒记录一次数据的时间关键型 C 代码。我还有一些 labview 代码可以操作不同的仪器并每 100 毫秒输出一个整数值。我希望我的 C 代码能够记录来自 labview 的值。做这个的最好方式是什么?

一种想法是让 Labview 循环将整数写入文件,并让 C 代码循环读取文件的值。(如有必要,我可以在我的 C 代码中添加第二个线程。) Labview 还可以链接到 C dll。所以我也许可以用 C 语言编写一个 DLL,以某种方式促进两个程序之间的共享。这是可取的吗?我该怎么做?

4

3 回答 3

4

我在这里有一个类似的应用程序,并使用带有 TCP_NO_DELAY 选项集的 TCP 套接字(禁用执行某种数据包缓冲的 Nagle 算法)。套接字应该允许 100 毫秒的更新速率没有问题,尽管实际的网络延迟将始终是一个未知变量。对于我的应用程序来说,只要它保持在某个限制以下就无关紧要(如果时间戳增量变得太大,还可以通过发送每个数据包的时间戳和红色大对话框来检查这一点:])。对你的申请有影响吗?即,每当 LV 仪器获取新样本时,它的值必须在 x 毫秒内到达 C 应用程序是否重要?

您可能会使用 dll 方法,但它不像套接字那么简单,它会使两个应用程序更加相互依赖。不过,可变访问几乎是即时的。我看到至少两种可能性:

  • 将你的整个C 应用程序放在一个 dll 中(起初可能看起来很奇怪,但它确实有效),并让 LV 加载它并在其上调用方法。例如,启动你的应用程序 LV 调用 dll 的 Start() 方法,然后在循环中 LV 获取它的样本,它调用 dll 的 NewSampleValue(0 方法左右。这也意味着你的应用程序不能独立运行,除非你为它编写一个单独的主机进程。
  • 查看共享进程内存,并让 C 应用程序和另一个 dll 共享公共内存。LV 将加载该 dll 并在其上调用一个方法以将一个值写入共享内存,然后 C 应用程序可以在轮询一个标志后读取它(这需要一个锁!)。
  • 也有可能让 C 应用程序使用 dll/activeX/ 调用 LV 程序?电话,但我不知道该系统是如何工作的..

我肯定会远离文件方法:磁盘 I/O 可能是一个真正的瓶颈,而且它还有锁定问题,这对于文件来说是很麻烦的。当 LV 正在写入文件时,C 应用程序无法读取文件,反之亦然,这可能会引入额外的延迟。

在旁注中,您可以看到上述每种方法都使用推式或拉式模型(TCP 可以以两种方式实现),这可能会影响您最终决定走哪条路。. Push = LV 表示C app 直接,pull = C app 必须轮询一个标志或向 LV 询问值。

于 2011-01-04T19:41:21.900 回答
3

我是 National Instruments 的一名员工,我想确保您不会错过 LabWindows/CVI(National Instruments C 开发环境)提供的网络变量 API。网络变量 API将允许您通过共享变量轻松与 LabVIEW 程序进行通信 (http://zone.ni.com/devzone/cda/tut/p/id/4679)。在阅读这些链接时,请注意网络变量和共享变量是同一个东西 - 不同的名称是不幸的......

网络变量 API 的好处是它允许与 LabVIEW 轻松互操作,它提供了强类型通信机制,并且它提供了一个回调模型,用于在网络/共享变量的属性(例如值)发生更改时进行通知。

您可以通过安装 LabWindows/CVI 获得该 API,但不必使用 LabWindows/CVI 环境。头文件位于C:\Program Files\National Instruments\CVI2010\include\cvinetv.h,位于C:\Program Files\National Instruments\CVI2010\extlib\msvc\cvinetv.lib的 .lib 文件可以与您使用的任何 C 开发工具链接。

于 2011-01-04T20:14:31.597 回答
3

我跟进了@stijn 的一个理想:

让 C 应用程序和另一个 dll 共享公共内存。LV 将加载该 dll 并在其上调用一个方法以将一个值写入共享内存,然后 C 应用程序可以在轮询一个标志后读取它(这需要一个锁!)。

我编写了 InterProcess 库,可在此处获得:http: //github.com/samuellab/InterProcess

CreateFileMapping()InterProcess 是一个紧凑的通用库,它使用和设置 Windows 共享内存MapViewOfFile()。它允许用户在任意数量的命名字段中无缝地存储任何类型的值(int、char、你的 struct.. 等等)。它还实现了 Mutex 对象以避免冲突和竞争条件,并将所有这些抽象到一个干净简单的接口中。在 Windows XP 上测试。应该适用于任何现代 Windows。

对于我现有的 C 代码和 labview 之间的接口,我编写了一个小型包装 DLL,它位于 InterProcess 之上,只公开我的 C 代码或 labview 需要访问的特定函数。这样,所有的共享内存就被完全抽象掉了。

希望其他人会发现此代码很有用。

于 2011-02-10T16:47:02.633 回答