Task separation involves running distinct tasks in parallel loops to create a multi-rate application. Task separation is a key aspect of most real-time applications for two reasons:

  • Determinism—To minimize jitter in a deterministic loop, ensure that the loop does not contain potentially non-deterministic code. Because most large applications include non-deterministic tasks, identifying and separating these tasks is crucial to the success of an RT application.
  • CPU Efficiency—Because CPU cycles often are at a premium on RT targets, CPU efficiency is a common design constraint in RT applications. By running tasks in separate loops at distinct rates, you can maximize CPU efficiency by executing each task only as often as necessary.

Define Your Tasks

Before you begin coding, think through the high-level design of your application by defining the tasks your application must perform, the required rate of each task (if applicable), and the data transfer relationships between the tasks. For example, your RT application requirements might include the following tasks:

  • Control—Control the temperature and level of liquid in a tank. The minimum rate for this task is 1 kHz.
  • Log—Log a historical record of the temperature and level data collected. The requirement for this task is to log every process variable value collected by the control task. There is no minimum rate requirement for this task.
  • Network—Transfer user interface data over the network to receive commands from the user and display continuous data graphs that the user can monitor. The minimum rate for this task is 10 Hz.

After you define the high-level tasks that make up your application, define the data transfer relationships between those tasks. For example, the following illustration shows the data transfer relationships between the three example tasks defined in the previous list:

Translate Your Design into a LabVIEW Block Diagram

After you define the high-level design of your application, you can begin translating your design into LabVIEW code. For example, the following block diagram shows a top-level VI that includes the ongoing tasks defined in the previous section:

Note In addition to the ongoing tasks that make up the bulk of your application, National Instruments recommends that you create an initialization task and a shutdown task, as shown in the previous block diagram.

The following block diagram shows the control loop contained in the Control.vi subVI:

The following block diagram shows the data logging loop contained in the Log.vi subVI:

The following block diagram shows the networking loop contained in the User_Interface.vi subVI:

Create an Initialization Routine

Create an initialization routine to handle preliminary tasks that need to occur before your ongoing tasks start executing. Depending on the nature of your application, an initialization routine might include the following actions:

  • Initialize shared variables
  • Open file references
  • Preallocate arrays

The following block diagram shows the initialization routine contained in the Initialize.vi subVI:

Create a Shutdown Routine

National Instruments recommends switching your application to a shutdown state before turning off your RT target. To ensure that your RT target is in a shutdown state, create a shutdown routine that runs after your ongoing application tasks stop executing. Depending on the nature of your application, a shutdown routine might include the following actions:

  • Set outputs to known values
  • Close file references
  • Notify the operator when they can turn off the RT target using a network-published shared variable or the RT LEDs VI
Note Even if your RT target uses the Reliance file system, you still can corrupt data by turning off the target while a file is open. Reliance protects the integrity of the file system itself in such cases but does not guarantee the integrity of individual files that remain open when you turn off the RT target.

The following block diagram shows the shutdown routine contained in the Shutdown.vi subVI.