Table of Contents
01 Architecture
Architecture Principles
General
-
When working with clusters and SubVIs, pass only the data the SubVI needs. Do not let the SubVIs consume the entire cluster.
-
See Passing Through
Structure
-
Adhere to the following:
Libraries and Classes
-
Wrap VIs in classes (.lvclass) or libraries (.lvlib) for name spacing and generally improved encapsulation
-
See Organising Code for details
-
Create a separate subfolder for each .lvlib or .lvclass that contains the container file and all members
Reentrancy
-
If a technology supports multiple threads (more than one instance in memory at the same time), all the VIs of the corresponding driver usually need to be set to reentrant execution.
Constants
-
For constants that are reused throughout the project, create a subVI that only contains a single constant on the block diagram and one indicator returning the constant value
-
See 00 Style for VI naming
-
See 02 Layout & Design for VI icon design
Database
-
Wrap each query in a separate SubVI
-
this allows for easy reuse
-
add documentation to describe the returned values
-
optional: convert the returned 2d-array of strings into a 1d-array of typedef'ed cluster
A DB connection is like a shared resource that cannot be used in parallel. (also true for SQLite)-
use one db connection instance per consumer to avoid blocking
Configuration
-
Simultaneous Creation: When creating access to a configuration file, the file and its related content must be created at the same time.
-
Focused SubVI Design: A configuration access SubVI should only contain related information. This minimizes dependencies and simplifies maintenance and testing.
-
Early Testing: Perform testing early to identify and resolve potential issues promptly, avoiding prolonged troubleshooting later.
-
Default Config Creation: Implement a VI that creates a configuration file in the correct format, even if the application does not have a “save config” requirement, ensuring consistency and avoiding potential issues.
Runtime Behaviour
Functions/Primitives
-
Do not use “First Call?”, use an FGV or AE instead
-
Working with frameworks that support dynamically starting and stopping, we often want to restart processes without having to restart the whole call chain or application.
-
Using a functional global variable that allows resetting the internal state on demand is more flexible and more readable than the “First Call?” primitive
-
See also Emmanuel Geveaux' LinkedIn article
Events
-
Watch 10 things (or more) to know about events in LabVIEW (Olivier Jourdan, Wovalab)
Event Registration
-
Maintain a single Event Structure per registration refnum
-
each registration creates a single event queue which must not be shared between event structures to avoid race conditions and non-deterministic behaviour
-
Do not fork the event registration reference wire (see previous point)
-
the only exception is for updating the registration - in that case, be very explicit with comments and explaining what to do and what not to do with the forked wire
Communication
-
Transferring data from one loop to another loop (VI-local)
-
Using VI server (reference or property node) to update the value of a control or indicator is the least efficient mechanism by far.
-
Local variables come with only a slight overhead to directly writing to the terminal.
-
Global variable would be the fastest with the additional caveats of race conditions and issues when global variables are not handled correctly.
-
RT FIFO or a User Event add context and encapsulation.
-
See the LabVIEW Craftsmen blog
LabVIEW Mechanisms
Variant Attributes
-
Do NOT use variant attributes for data storage unless their high performance is definitely needed.
-
Attributes hide away any information about the datatypes at edit time
Structures
Unwired Terminals
-
Use “Use Default If Unwired” appropriately
-
If no default value should ever be used, enable “Linked Input Tunnel”
Conditional Disable Structures
-
When using CD Structures, put them into the project tree:
-
as far up as possible (ie. direct at the project root level, as opposed to the targets)
-
as far down as necessary (eg to distinguish different FPGA targets)
-
For each CD Symbol in the project, add a log entry or similar to your project so you can identify at runtime which values were defined for the symbols
-
Put these into a subVI directly after starting the application
-
When using HSE libs, put this subVI directly after initialising the HSE-Logger
Data Design
Comparison
-
For floating point values, do not use the “Equals?” function. Due to the resolution of the datatype, values might differ in the decimal places. One possible solution is to use “In Range?” with upper and lower limits instead.
Array to Cluster Conversion
-
The Array to Cluster node has the number of elements hard-coded
-
As an array is dynamic, we need to check the size during runtime
-
To convert the generic cluster to a typedef-ed one, use the Coerce To Type function
Timestamps
-
When needing timestamp information in string format (logging, file names, etc.), always use the Format to String function with extended format specifiers (
%<…>T) to have complete control over the output format-
This avoids errors with special characters like “/” or “:”
-
See Format Codes for the Time Format String in the LV help
Front Panel Interaction
These guidelines cover reading and writing of front panel element properties (e.g. visibility, color, enable/disable), not values. Reading or writing control values via references or property nodes is generally discouraged.
General principles
-
Avoid updating FP elements via value property nodes whenever possible.
-
Prefer the simplest possible implementation.
-
It must be easy to find where a specific FP element is interacted with.
-
Do not pass references “just in case”; only pass what is actually needed.
-
Prefer explicit, type-safe, and local solutions over dynamic or generic abstractions.
Approaches
Choose the simplest suitable one:
1. Local Property Nodes
Place property nodes directly linked to the FP element.
-
Pros:
-
Maximum readability and traceability
-
No indirection, easy to debug
-
Strong visual coupling between UI and logic
Cons:-
Not reusable
-
Can clutter the diagram if overused
2. Pass minimal FP references to SubVIs
If a SubVI is required, pass only the specific references it needs.
-
Pros:
-
Good balance between reuse and clarity
-
Explicit dependencies
-
Still easy to trace usage
Cons:-
Slight increase in wiring effort
-
Tight coupling between caller and SubVI
3. Cluster of type-specific references
Group FP references into a cluster with strict typing. Use Unbundle/Bundle (and Build Array where applicable).
-
Pros:
-
Native LabVIEW solution (simple, stable, no extra abstractions)
-
Type-safe and searchable
Cons:-
SubVIs may receive references they do not use
-
Slightly reduced clarity of “who uses what” (but still visible on BD)
-
FP of subVI may show a huge cluster
4. Map-based approach (generic references + enum access)
Store references in a map using generic types and access via enum.
-
Pros:
-
Clean and flexible interface
-
Enables more dynamic behavior
Cons:-
Higher complexity and indirection
-
Reduced safety
-
Harder to debug
-
more effort to maintain the enum
Rule:-
Only use if there is a clear, documented benefit. Otherwise avoid.
Project Hygiene
Dependencies
-
Check and tidy your dependencies (project)
-
Try and move as many dependencies as possible into your project repo
-
Leave only files from symbolically linked locations (vi.lib, instr.lib, …)
-
Any VIs or controls that are loaded from a different path than the ones mentioned above will make LabVIEW link statically to those files, which will cause problems sooner or later.
-
Save only what you changed on intention. Avoid “Save all”.
-
For SCC: Commit only files you actually changed.
-
For SCC: Commit in groups of changes (commit often).
-
Separate compiled code from source file for all VIs and libraries
-
VI properties → General → Separate compiled code from source file: Check
-
When LV crashes and recovers files from the auto-saved backup, those recovered VIs don't have the flag set (might be fixed in LV 2020)
File System
-
Remove unused/deprecated/old code (VIs) immediately!
-
tidy up ASAP to avoid propagation, also later on time might be of the essence
-
Keep test VIs outside the project if they are not used by the application
-
Alternative: Make them part of the library they cater to, document etc.
The HSE Way of Working:
A set of guidelines that recommend programming style, better practices, and methods for all our LabVIEW projects. We ask all our peers to follow these guidelines to help improve the readability of our shared source code and make software maintenance easier. -
kb/bestpractices/codingconventions/architecture.txt · Last modified: 2026/07/30 07:41 by joerg.hampel
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




