将应用程序中的任务分为独立的定时循环或不同优先级的VI后,程序框图的循环之间或RT终端上不同的VI之间可能需要进行通信。使用共享变量和Real-Time FIFO VI在RT终端上的VI之间和VI内部共享数据。

注: 也可使用全局变量和功能全局变量在本地共享数据。但是,这些通信方法会对确定性产生不利影响。

单进程共享变量

使用单进程共享变量在程序框图的两个位置之间,或RT终端上的两个VI之间传递数据。在项目浏览器窗口右键单击RT终端,从快捷菜单中选择新建»变量,打开共享变量属性对话框,从中创建单进程共享变量。

Real-Time模块向共享变量添加了实时FIFO(先进先出缓存)功能。通过启用共享变量的RT FIFO功能,可共享数据而不影响RT终端上VI的确定性。在共享变量属性对话框的“Real-Time FIFO”页,勾选启用Real-Time FIFO复选框,即可启用共享变量的实时FIFO。

启用RT FIFO之后,单进程共享变量是易用且确定性高的通信方法。

注: 如使用启用Real-Time FIFO的共享变量传输波形数据,共享变量不传输波形中的变体元素,因为变体的大小不确定,与Real-Time FIFO不兼容。

Real-Time FIFO函数

使用RT FIFO函数在RT终端上运行的VI之间共享数据。RT FIFO类似一个固定大小的队列,写入FIFO的第一个值是能从FIFO读取的第一个值。RT FIFO限制共享数据的大小,并为数据预分配内存,以保证程序执行的确定性。必须定义RT FIFO元素的数量和大小,确保不读取和写入不同大小的数据。

使用RT FIFO创建函数创建一个新的FIFO,或创建对之前已存在FIFO的引用。使用RT FIFO读取和RT FIFO写入函数,读取和写入数据至FIFO。使用RT FIFO删除函数删除RT FIFO的引用,释放RT终端上分配的内存。

注: 如使用Real-Time FIFO传输波形数据,则无法传输波形的变体元素,因为变体的大小由变量确定,与Real-Time FIFO不兼容。

定义Real-Time FIFO的读取和写入模式

RT FIFO会等待直到有空槽可写入或有值可读取时,才执行读取或写入操作。用户可指定RT FIFO的写入和读取模式。写入和读取模式定义了从空的FIFO读取或写入已满的FIFO时的处理方式。可指定下列读取或写入模式:

轮询-该模式能最大化读取和写入操作的数量。轮询模式连续轮询FIFO,检测是否有新数据或空槽。轮询模式对新数据的新出现空槽的响应比阻隔模式更快,但是需要更多的CPU开销。使用RT FIFO读取或RT FIFO写入函数的超时(ms)输入端指定写入操作轮询空槽或读取操作轮询新进数据的时间。也可使用RT FIFO写入VI的超时覆盖输入端指定当超时毫秒输入端的值过期时,是否覆盖RT FIFO中最早写入的值。

阻隔-该模式下,读取和写入操作的CPU利用率最好。阻隔模式使VI的线程等待时进入休眠状态,允许系统中其他任务执行。使用RT FIFO读取或RT FIFO写入函数的超时(ms)接线端指定读取操作等待新值的时间,或写入操作等待空槽的时间。也可使用RT FIFO写入VI的超时覆盖输入端指定当超时毫秒输入端的值过期时,是否覆盖RT FIFO中最早写入的值。

注: 如使用“RT FIFO创建”函数返回现有RT FIFO的引用,引用使用现有FIFO的读取和写入模式,忽略“读取/写入模式”接线端指定的模式。

使用RT FIFO函数创建大型应用程序的可扩展程序框图

如要为大型应用程序创建一个可扩展的任务间通信架构,使用“RT FIFO创建”函数,通过编程创建RT FIFO。例如,可在For循环中使用“RT FIFO创建”函数,创建所需数量的RT FIFO。然后在For循环中使用RT FIFO读取和RT FIFO写入函数,连续从RT FIFO中写入和读取数据。通过该方法,可方便地扩展应用程序的RT FIFO,同时保持程序框图整洁易读。

注: 使用RT FIFO创建函数的轮询模式,优化读取和写入操作的速度。使用阻隔模式,减少CPU开销。轮询模式连续轮询FIFO,检测是否有新数据或空槽。轮询模式对新数据的新出现空槽的响应比阻隔模式更快,但是需要更多的CPU开销。在多CPU系统中,考虑使用轮询模式并为轮询RT FIFO函数分配专有的CPU。

全局变量

使用全局变量在两个VI之间访问和传递少量数据,例如,实时VI和低优先级VI。全局变量可在两个VI之间确定性地共享小于32位的数据,例如,换算数据。全局变量的数据类型较大,是共享资源,必须在实时VI中谨慎使用。如使用数据类型大于32位的全局变量将输出从实时VI中传出,必须保证实时VI再次写入全局变量之前,由较低优先级的VI读取全局变量的数据。

全局变量不是一种严格的通信方式,全局变量的值如未被及时读取,就有可能会被覆盖。较低优先级VI中的VI可能没有足够的时间在其他VI的任务覆盖数据之前先读取数据。

功能全局变量

功能全局变量用于在VI之间传输数据。功能全局变量是设置为子程序优先级的子VI。子VI包含一个While循环,While循环中又有一个进行读取和写入操作的条件结构。下列程序框图显示了功能全局变量中条件结构的读/写分支:

While循环包含未初始化的移位寄存器,用于存储数据。功能全局变量的模式输入参数接收一个指定VI进行任务的操作输入,如上述程序框图所示。从这步之后对功能全局变量的调用都可访问最新的数据。功能全局变量类似于队列,可添加更多的移位寄存器来保存更长历史记录。也可添加一组以上移位寄存器,传递更多数据。

与共享变量不同,功能全局变量不是共享资源。右键单击子VI,设置为子程序优先级并从快捷菜单中选择遇忙时跳过子程序调用。如子程序被调用时正在其他线程中运行,则跳过子VI。实时VI不等待在其他线程中运行的子VI,跳过子VI有助于保证实时VI的确定性。跳过子VI执行程序,子VI返回的值可能有误。如要检测功能全局变量的执行,将TRUE常量连接至功能全局变量的布尔输出,保证显示控件的默认值为FALSE。如布尔输出返回TRUE,功能全局变量执行。如布尔输出返回默认值FALSE,功能全局变量不执行。在实时VI中跳过功能全局变量,但在低优先级VI中不跳过,可以等待接收非默认值。

VI读取移位寄存器的值之前,移位寄存器的值可能被覆盖,所以,功能全局变量不是一种严格的通信方式。