When implementing code modules, there are many design decisions that will impact many of the code modules you create. This section provides guidelines for the following concepts:
- Communicating data from TestStand to code modules
- Handling sequence termination within code modules
- Reporting code module errors to TestStand
- Managing code module execution speed and memory usage
Communicating Data from TestStand to Code Modules
There are two approaches you can use to access TestStand data within a code module:
- Pass the data through code module parameters
- Access the data directly within the code module using the TestStand API
In most cases, it is a better idea to use parameters to pass data rather than the TestStand API to access them directly for the following reasons:
- Less error prone - Any errors in the property names or data types will be easy to find since the parameter values are defined in the step type settings in TestStand, not directly in the code module.
- More maintainable - Changes to step properties are specified in the parameter configuration in TestStand without any modifications to the code module.
- Easier to reuse outside of TestStand - Since the code module does not rely on the TestStand API, the module can be used outside of TestStand with no modification
When possible, use parameters to pass in required data to code modules
However, using the API to directly access properties can be useful in cases where the code module is accessing a variety of data dynamically, based on the state of the step. Using step parameters in this case can lead to a long list of parameters where only some are actually used in various conditions.
If you do use the TestStand API in a code module, pass a reference to the SequenceContext object (ThisContext) as a parameter. the SequenceContext object provides access to all other TestStand objects, including the TestStand engine and the current Runstate. The sequence context reference is also necessary if you are using the termination monitor or modal dialog VIs.
Use the SequenceContext to access the TestStand API in code modules, which can be used to access data programmatically
If you are reusing code modules outside of TestStand, keep in mind that any operations which use the TestStand API will only be available if the module is called from a TestStand sequence. Any data the module obtains from TestStand through the API will not be available. You can define an alternate mechanism for obtaining test data in cases where the code module is called outside of TestStand by first checking if the Sequence Context reference is null. In LabVIEW, you can use the Not A Number/Path/Refnum? function, which returns a Boolean value, as shown in Figure 3.
Use Not a Number/Path/Refnum? to check validity of the SequenceContext Object Reference for code modules used outside of TestStand
Handling Large Data Sets in Code Modules
In many cases, code modules can produce large amounts of complex data from measurement or analysis. Avoid storing this type of data in TestStand variables, since TestStand creates a copy of the data when storing it. These copies can reduce runtime performance and/or cause out of memory errors. Use the following approaches to manage large data sets without creating unnecessary copies:
- Operate on large data sets inside the code modules, such as analyzing data in the same code module it is acquired, and only return required results to TestStand
- Pass data pointers between TestStand and code modules. For LabVIEW code modules, use Data Value References (DVRs)
Handling Sequence Termination within Code Modules
When a user presses the Terminate button, TestStand stops the executing sequence and runs any Cleanup steps. However, if the execution has called a code module, the module must complete execution and return control back to TestStand before the sequence can terminate. If the run time of a code module is longer than a few seconds or when the module waits for a condition to occur, such as user input, it can appear to the user that the terminate command was ignored.
To address this issue, you can use the termination monitor to allow code modules to check and respond to the termination status of the calling execution. For example, the Computer Motherboard Test shipping example uses the termination monitor in the simulation dialog, as shown below. If the test sequence is terminated, the Check Termination state VI returns false, and the loop is stopped.
Refer to the termination monitor examples for more information on using the termination monitor.
An error in a test system is an unexpected run-time behavior that prevents testing from being performed. When a code module generates an error, pass that information back into the test sequence to determine what action to perform next, such as terminating the execution, repeating the last test, or prompting the test operator.
To provide TestStand with any error information from code modules, use the Result.Error container of the step, as shown below. TestStand automatically checks this property after each step to determine if an error occurred. You do not need to pass the error information from TestStand into the code module. If the code module returns an error to TestStand, execution can branch to another part of the test sequence, such as to the Cleanup step group.
You can use the On Run-Time Error setting, located in the Execution tab of the Station Options to determine how TestStand responds to step errors. Typically, you should use the Show Dialog Box option while developing your sequences to assist in debugging, since this option allows you to break the execution and check the current state of the sequence. For deployed systems, consider using the Run Cleanup or Ignore options to rather than requiring input from test operators. Error information is automatically logged to the test results, which can be used to find the cause of the error.
Pass error information to the Step.Result.Error container to notify TestStand if a step error occurs
Managing Performance and Memory Usage of Code Modules
By default, TestStand loads all code modules in a sequence file into memory when you execute a sequence in the file and keeps them loaded until you close the sequence file. With these settings, an initial delay can occur when you start a sequence while the modules are loaded. However, subsequent executions of the sequence file are faster since the modules remain in memory.
You can configure when a code module is loaded and unloaded in the Run Options tab of the step settings pane. Typically, the default load options provide the best performance, but in some cases it can be better to load the code module only when it is used with the Load dynamically load option. For code modules that are not called in typical execution, such as diagnostics which only run after a particular test fails, should be loaded dynamically since in most cases these modules do not need to be loaded at all.
When you dynamically load code modules, be aware that TestStand does not report issues for the code modules until it loads the code module, which could be toward the end of a lengthy execution. However, you can use the sequence analyzer to verify that there are no errors in a sequence before executing. The analyzer will check both statically and dynamically loaded code modules.
For memory intensive code modules, you can modify the default unload option to reduce total memory usage. For example, setting the module to Unload After Step Executes or Unload After Sequence Executes. However, this change will increase execution times, since TestStand will need to reload the module for each subsequent call. When possible, a better alternative is to use the 64-bit version of TestStand and a system with more physical memory to get the fastest test performance despite high memory usage requirements.
If your code modules maintain shared data, such as static variables or LabVIEW functional global variables, modifying unload options can cause changes in behavior, since global data is lost when modules are unloaded. When changing unload options, be sure that any required data is either passed to the TestStand sequence or stored in a more permanent location to prevent data loss.
Refer to Best Practices for Improving NI TestStand System Performance for more information about other ways to optimize the performance of a test system.