|Download Help (Windows Only)|
After dividing tasks in an application into separate Timed Loops or VIs of different priorities, you might need to communicate between the loops on a block diagram or between the different VIs on the RT target. Use shared variables and Real-Time FIFO VIs to share data in a VI or between VIs running on an RT target.
|Note You also can use global variables and functional global variables to share data locally. However, these communication methods are lossy and can compromise determinism.|
Use single-process shared variables to share data between two locations in a block diagram or between VIs running on an RT target. Right-click an RT target in the Project Explorer window and select New»Variable from the shortcut menu to open the Shared Variable Properties dialog box, which you can use to create a single-process shared variable.
The Real-Time Module adds real-time FIFO (first in, first out) buffer capability to the shared variable. By enabling the real-time FIFO of a shared variable, you can share data without affecting the determinism of VIs running on an RT target. From the Real-Time FIFO page of the Shared Variable Properties dialog box, place a checkmark in the Enable Real-Time FIFO checkbox to enable the real-time FIFO of a shared variable.
Single-process shared variables provide a communication method that is easy to use and deterministic when you enable the Real-Time FIFO.
|Note If you enable the Real-Time FIFO on a shared variable of waveform datatype, the variant element of the waveform does not transfer because variants are variable-sized and therefore incompatible with the Real-Time FIFO.|
Use the RT FIFO functions to share data between VIs running on an RT target. An RT FIFO acts like a fixed-sized queue, where the first value you write to the FIFO is the first value that you can read from the FIFO. An RT FIFO ensures deterministic behavior by imposing a size restriction on the data you share and by preallocating memory for the data. You must define the number and size of the RT FIFO elements and ensure that you do not attempt to read and write data of different sizes.
Use the RT FIFO Create function to create a new FIFO or to create a reference to a FIFO that you previously created. Use the RT FIFO Read and RT FIFO Write functions to read and write data to the FIFO. Use the RT FIFO Delete function to delete a reference to an RT FIFO and release the memory allocated to the FIFO on the RT target.
|Note If you use a Real-Time FIFO to transfer waveform data, the variant element of the waveform does not transfer because variants are variable-sized and therefore incompatible with the Real-Time FIFO.|
An RT FIFO can wait until an empty slot becomes available for a write operation or wait until a value is available for a read operation. You can specify a read and write mode for an RT FIFO that defines the way you read a value from an empty FIFO or write a value to a FIFO that does not have an empty slot. You can specify one of the following modes for reads and writes:
polling—Use this mode to optimize the throughput performance of read and write operations. The polling mode continually polls the FIFO for new data or an open slot. The polling mode responds quicker than the blocking mode to new data or new empty slots, but requires more CPU overhead. Use the timeout in ms input of the RT FIFO Read or RT FIFO Write function to specify the amount of time that a write operation should poll for an empty slot or the amount of time a read operation should poll for new data. You also can use the overwrite on timeout input of the RT FIFO Write VI to specify whether to overwrite the oldest value in the RT FIFO when the value of the timeout in ms input expires.
blocking—Use this mode to optimize the utilization of the CPU during read and write operations. The blocking mode allows the thread of the VI to sleep while it waits, allowing other tasks in the system to execute. Use the timeout in ms input of the RT FIFO Read or RT FIFO Write function to specify an amount of time a read operation can wait for a new value or an amount of time a write operation can wait for an empty slot. You also can use the overwrite on timeout input of the RT FIFO Write VI to specify whether to overwrite the oldest value in the RT FIFO when the value of the timeout in ms input expires.
|Note If you use the RT FIFO Create function to return a reference to an existing RT FIFO, the reference uses the read and write mode of the existing FIFO and ignores the modes specified with read/write modes.|
When you need a scalable inter-task communication architecture for a large application, use the RT FIFO Create function to create RT FIFOs programmatically. For example, you can use the RT FIFO Create function inside a For Loop to create as many RT FIFOs as you need. You then can use the RT FIFO Read and RT FIFO Write functions inside For Loops to read from and write to all your RT FIFOs consecutively. Using this technique, you can scale your application up to use as many RT FIFOs as you need while keeping the size of your block diagram manageable.
|Tip Use the polling mode of the RT FIFO Create function to optimize the throughput performance of read and write operations. Use the blocking mode to minimize CPU overhead. The polling mode continually polls the FIFO for new data or an open slot. The polling mode responds quicker than the blocking mode to new data or new empty slots, but requires more CPU overhead. In a multiple-CPU system, consider using polling mode and assigning the polling RT FIFO function to a dedicated CPU.|
Use global variables to access and pass small amounts of data between VIs, such as from a time-critical VI to a lower priority VI. Global variables can share data smaller than 32-bits, such as scalar data, between VIs deterministically. However, global variables of larger data types are shared resources that you must use carefully in a time-critical VI. If you use a global variable of a data type larger than 32-bits to pass data out of a time-critical VI, you must ensure that a lower priority VI reads the data before the time-critical VI attempts to write to the global again.
Global variables are a lossy form of communication, meaning the global variable can overwrite the data before you read the data. Tasks in a lower priority VI might not have enough processor time to read the data before other tasks in a different VI overwrite the data.
Use functional global variables to pass data between VIs. A functional global variable is a subVI set to subroutine priority. The subVI contains a While Loop with a nested Case structure for read and write access. The following block diagram shows the read and write cases of the Case structure for a functional global variable:
The While Loop contains uninitialized shift registers that store data. A functional global variable receives an action input that specifies which task the VI performs, as shown in the previous block diagram, by the Mode input parameter. Any subsequent calls to the functional global variable can access the most recent data. Functional global variables resemble queues because you can add more shift registers to store a longer history of values. You also can add more than one set of shift registers to pass more than one set of data.
Unlike global variables, you can implement functional global variables such that they are not a shared resource. Right-click a subVI set to subroutine priority and select Skip Subroutine Call If Busy from the shortcut menu to force the execution system to skip the subVI if the subVI is currently running in another thread. Skipping a subVI helps in time-critical VIs because the VI does not wait for the subVI. If you skip the execution of a subVI, the subVI returns the default indicator value. If you want to detect the execution of a functional global variable, wire a TRUE constant to a Boolean output on the functional global variable block diagram, and ensure that the default indicator value is set to FALSE. If the Boolean output returns TRUE, the functional global variable executed. If the Boolean output returns the default value of FALSE, the functional global variable did not execute. Skip functional global variables in time-critical VIs but not in lower priority VIs. In lower priority VIs, you can wait to receive non-default values.
Functional global variables can be a lossy form of communication if a VI overwrites the shift register data before another VI reads the data.