IVI.NET Driver Walkthrough
In this walkthrough, you will create a simple IVI.NET driver along with a help file and installer.
This walkthrough will consist of the following nine main steps:
- Creating the IVI.NET driver project
- Defining an enumerated type
- Adding a method
- Implementing a method using the Instrument Command Editor
- Adding a property that uses an enumerated type
- Building the driver
- Testing the driver
- Creating the help file
- Creating the driver installer
Creating the IVI.NET Driver Project
We’ll create a new driver project calledAcme4321. Nimbus is completely integrated with Microsoft Visual Studio, so the process of creating an IVI.NET driver project begins with the same steps required to create any Visual Studio project.
To create the Acme4321 driver
Section titled “To create the Acme4321 driver”-
Open Visual Studio.
-
From the File menu, choose New Project.
-
Select IVI.NET Projects from the list of installed project templates shown on the left.
-
Select IVI.NET Driver from the list of project types shown on the right.
-
In the Name box, enter
Acme4321. -
Click Next.
The IVI.NET Driver Wizard appears.
-
On the General Page, specify the following:
- For Instrument manufacturer, enter
Acme Corporation. - For Driver vendor, enter
Pacific MindWorks. - For .NET assembly name prefix, enter
Acme. - For Instrument model, enter
Acme4321.
- For Instrument manufacturer, enter
-
Press Next.
-
On the IVI Instrument Classes Page, leave all instrument classes unchecked.
-
Press Next.
-
On the LXI Compliance Page, select the None radio button.
-
Press Next.
-
On the Projects Page, check each of the available project types except Create IVI.NET Visual Basic console application.
-
Click Finish to create the project.
The Visual Studio Solution Explorer will automatically open, showing each of the following projects:
-
Acme4321
This is the Nimbus Project, which manages each of the other related projects in the solution for this driver.
-
Acme4321CsConsoleApplication
A sample C# console application that can be used to exercise the driver, or be released as sample code.
-
Acme4321Driver
The standard C# class library assembly project that will contain all of the code for this driver.
-
Acme4321Help
The driver help project that will build the help file(s) for this driver.
-
Acme4321Setup
The driver setup project that you’ll use to customize and build the installer for the driver.
-
Acme4321UnitTest
The standard Visual Studio unit test project that will be used to test the driver.
-
-
In the Solution Explorer, double click the Driver Designer node that’s displayed under the Acme4321 Nimbus Project.
The Nimbus driver designer appears.
Defining an Enumerated Type
Enumerated types are commonly used as property types and parameter types. Nimbus provides special support for defining enums and using them in method and property instrument commands.To define an enum:
Section titled “To define an enum:”-
Expand the Acme.Acme4321 assembly node in the driver designer. This will reveal the following child nodes:
-
Hierarchy
This is the main designer node under which most of the driver modifications described below will be performed.
-
Interfaces
This node lists the interfaces defined in the driver assembly.
-
Classes
This node lists the classes defined in the driver assembly.
-
Structs
This node lists the structures defined in the driver assembly.
-
Delegates
This node lists the delegates defined in the driver assembly.
-
Enums
This node lists the enumeration types defined in the driver assembly. You’ll be using this momentarily to define a custom enum.
-
Exceptions
This node lists the exception classes defined in the driver assembly.
-
-
Right-click on the Enums node and choose Add Enum.
A new enum node is added with a default name and the node enters edit mode.
-
For the name, simply enter
TriggerSourceand hit Enter. -
We need to add three enum members to the
TriggerSource. Right-click on theTriggerSourceand choose Add Enum Member.A new enum member is added to the enum with a default name and the enum member enters edit mode.
-
Enter
Internalfor the member name and hit Enter. This will complete the addition of the new enum member, and display the Enum Member Editor. -
Enter
INTfor the Command value shown in the Enum Member Editor. This value will be used by Nimbus whenever automatic instrument command formatting is leveraged by the driver developer. -
Right-click again on the
TriggerSourceand add an enum member namedExternal. Set its instrument Command value toEXT. -
Finally, add an enum member named
Software. Set its instrument Command value toSW.
Adding a Method
When you add new functionality to a driver, you organize the methods and properties in a hierarchy, which corresponds to interfaces that Nimbus will create and manage.To add a Configure method with parameters:
Section titled “To add a Configure method with parameters:”-
Expand the Hierarchy node in the driver designer to reveal the methods and properties already added to your driver by Nimbus when the driver solution was created.
Methods and properties shown greyed out indicate that they cannot be modified. This is because those methods and properties are inherited from the IVI-defined
IIviDriverinterface. -
Right-click on the Hierarchy node and choose Add Method.
A new method node is added to the hierarchy with a default name, and the node enters edit mode.
-
Enter the following as the name and signature of the new method and then press the Enter key:
Configure(int numRecords, bool enabled) -
Expand the newly created Configure node and notice that Nimbus automatically created both the
numRecordsandenabledparameters requested above. -
Right-click on the Configure method node and select Add Parameter.
A new parameter node is added to the Configure method with a default name, and the node enters edit mode.
-
Enter the following as the name and signature of the new parameter and then press the Enter key:
source : TriggerSourceIf you are prompted to resolve the ambiguity between two different
TriggerSourcetypes, pick the instrument-specific one — the one defined in the Acme4321 assembly.
Implementing a Method Using the Instrument Command Editor
Although Nimbus supports developing drivers for any type of instrument — register-based, message-based, or custom I/O devices, special features are provided that make message-based IVI.NET driver development particularly efficient. Every method or property can be implemented by associating an instrument command with the method or property. Nimbus can be instructed to automatically format the runtime value of method parameters into the instrument command string. This section of the walkthrough will present some of the automatic instrument command formatting features provided by Nimbus.To implement a method using an instrument command:
Section titled “To implement a method using an instrument command:”-
Select the
Configuremethod node in the IVI.NET Driver Designer. -
From the Item Editor, change the Implementation style to be Instrument Command. This enables the Command text box.
-
In the Command text box, enter the following command (although you could copy/paste this command, don’t do so at this time so that a feature of this editor can be demonstrated):
ACQ:CONFIG {numRecords},{enabled}; TRIG:SOUR {source}The above command uses parameter tags enclosed in curly braces (
{ }) to insert the runtime value of parameters into the command. Notice that when you type a left curly brace ({), Nimbus presents an IntelliSense context menu from which you can select the desired parameter to use in the instrument command. -
Right-click on the Configure method node and select Go to Implementation.
Nimbus will open the source file containing the method’s implementation (
Acme4321.cs), and then navigate to the location within that source file where that method resides. It should look as shown below:[DriverMethod]public void Configure(int numRecords, bool enabled, TriggerSource source){if (this.Session.InitOptions.SimulationEnabled){throw new NotImplementedException(); // TODO}this.IO.FormattedIO.PrintfAndFlush("ACQ:CONFIG %d,%s; TRIG:SOUR %s", numRecords, enabled, source);} -
The implementation of the
Configuremethod needs to be modified so that it works in simulation mode — that is, when no device is physically available. (This is important for steps later in this walkthrough.) The driver designer has already generated the code necessary to test theSimulationEnabledproperty, which will returntrueif the driver is being used in simulation mode. But the designer has left the remainder of the simulation-mode implementation for the developer to complete. Since the designer doesn’t know what’s appropriate, it always generates code to raise aNotImplementedExceptionexception. All we need to do is replace the boilerplate code with something more appropriate.Delete the
TODOcomment and replace thethrow new NotImplementedException();statement with a simplereturn;statement. These changes allow theConfiguremethod to operate when the driver is used in simulation mode.The
Configuremethod should now look as follows:[DriverMethod]public void Configure(int numRecords, bool enabled, TriggerSource source){if (this.Session.InitOptions.SimulationEnabled){return;}this.IO.FormattedIO.PrintfAndFlush("ACQ:CONFIG %d,%s; TRIG:SOUR %s", numRecords, enabled, source);} -
Each parameter used in the instrument command is formatted according to its data type and Nimbus configuration options. Note that the
numRecordsparameter will be formatted using the%dformat specifier, while both theenabledandsourceparameters will be formatted using the%sformat specifier. -
Because the
sourceparameter is an enumerated type (TriggerSource), the Command values previously configured for each of its three enum members will be sent to the instrument based on the value of thesourceparameter. For example, if thesourceparameter value isTriggerSource.External, the instrument command value will beTRIG:SOUR EXT.The formatting used for numeric and boolean values is configured at the Nimbus project level.
Right click on the Acme4321 project in the Solution Explorer and select Driver Settings Editor. This will display the IVI.NET Driver Settings.
-
Click on the I/O tab. This will display the instrument command formatting editor.
-
Note that format specifiers for integer and floating point data types have been provided (
%dand%0.15g, respectively). Also note that the default values to use for booleans have been provided (1and0fortrueandfalse, respectively).Change the Boolean True field from
1toON.Change the Boolean False field from
0toOFF.
Adding a Property That Uses an Enumerated Type
Enumerated types are commonly used as property types as well as for parameter types.To define a property that uses an enum:
Section titled “To define a property that uses an enum:”-
We’ve already defined the
TriggerSourceenum type, so to define a property that uses that type, simply right-click on the Hierarchy node in the driver designer, and select Add Property.Enter the following and then press the Enter key:
SweepSource : TriggerSourceThe General tab of the property item editor will appear to the right.
-
With the
SweepSourceproperty selected in the tree view, change the Implementation style in the Item Editor to Instrument Command. -
For the Setter command, enter the following command that will be sent to the device when the property value is written:
TRIG:SOUR {value}For the Getter command, enter the following query that will be sent to the device when the property value is read:
TRIG:SOUR?The setter command instructs Nimbus to take the value of the property and place it in the command in place of the
{value}parameter tag. For reads from the instrument, first the Getter command is sent, and then Nimbus reads from the device and parses the response according to the Getter response specified. For theSweepSourceproperty, leave the Getter response set to{value}, which simply means that the device responds by sending a value that Nimbus will parse into one of the allowedTriggerSourcevalues. -
Right click on the newly created SweepSource property node in the driver designer and select Go to Implementation. Nimbus should navigate you to the implementation of the new SweepSource property, which should look as follows:
[DriverProperty][Simulation(SimulationMode.LastValue, Default = "Internal")]public TriggerSource SweepSource{get{this.IO.FormattedIO.PrintfAndFlush("TRIG:SOUR?");Acme.Acme4321.TriggerSource value;this.IO.FormattedIO.Scanf("%s", out value);return value;}set{this.IO.FormattedIO.PrintfAndFlush("TRIG:SOUR %s", value);}}Note that, unlike it did for the
Configuremethod, the Nimbus driver designer did not generate any boilerplate code that needs to be replaced before using this property. The implementation of both the property getter and setter is completely filled in and requires no further updates.Furthermore, simulation support has been enabled by default via the use of the
SimulationAttributeattribute. This is accomplished automatically by the Nimbus code weaver.
Building the Driver
To build the driver:
Section titled “To build the driver:”-
The first step in compiling a Nimbus driver is properly setting the build configuration. This only has to be done once the first time a new driver project is created, and is described in more detail here.
-
From Solution Explorer, right click on the solution and choose Configuration Manager. The Configuration Manager Dialog Box appears.
-
From the Active solution platform combo box, choose <Edit…>. The Edit Solution Platforms dialog box appears.
-
The following shows the list of platforms will be listed:
- Any CPU
- Mixed Platforms
- x64
- x86
-
Remove all platforms except for Mixed Platforms.
-
Close the Edit Solution Platforms dialog.
-
Back in the Configuration Manager dialog, make sure that the Platform column setting and Build column setting for each project is set according to the table below.
Project Platform Build Acme4321CsConsoleApplication x86 Checked Acme4321Driver Any CPU Checked Acme4321Help Any CPU Unchecked Acme4321Setup x86 Unchecked Acme4321UnitTest Any CPU Checked -
After making the above changes to both the Debug and Release configurations, close the Configuration Manager dialog.
-
Make sure Mixed Platforms is selected in the Solution Platforms combo box.
Also make sure Debug is selected in the Solution Configurations combo box.
-
From the Build menu, select Build Solution. You can also initiate the build by right-clicking on the Solution node in the Solution Explorer and choosing Build Solution.
-
The driver is now ready to use in an application. The build process automatically registers the driver with the IVI Configuration Store. You can use a 3rd-party IVI browser, such as Measurement Automation Explorer® (MAX) from National Instruments® to view the IVI Configuration Store.
Testing the Driver
Nimbus-generated driver unit test projects integrate directly into Visual Studio’s unit testing environment. As you use the Nimbus driver designer, Nimbus creates, deletes and updates unit test methods for each driver method, property and event, which can then be executed using Visual Studio’s unit testing framework.To run the driver unit tests
Section titled “To run the driver unit tests”-
From the Visual Studio Test menu, choose Windows and then select Test View.
-
The Test View window appears docked within Solution Explorer, and will display all of the unit test methods Nimbus has already created for the driver.
Pull down the Group By combo box within the Test View and select Class Name. This will organize the unit test methods according to the unit test classes in which those test methods are defined. Nimbus creates one unit test class per interface defined within the driver project. The following unit test classes should be visible:
- IAcme4321Test
- IIviDriverIdentityTest
- IIviDriverOperationTest
- IIviDriverTest
- IIviDriverUtilityTest
-
Expand the test class node for the IAcme4321Test class, right-click on the
SweepSourceproperty and choose Open Test. -
Nimbus navigates to the C# unit test method for the
SweepSourceproperty. The test code for this method sets the value of the property, reads back the value in the instrument, and then compares the value set to the value read to ensure that the property worked. It repeats this sequence for each of the three members of theTriggerSource.Also note that the unit test method has a
[TestMethod]attribute applied. This is a standard Visual Studio attribute that Nimbus uses to mark this method as a unit test method for the Visual Studio unit testing engine. -
Go to the top of the
IAcme4321Testtest class source file.Notice that the following two methods are defined:
_Init, and_Close. The_Initmethod has a[TestInitialize]attribute applied, and the_Closemethod has a[TestCleanup]attribute applied. Those attributes are standard Visual Studio attributes that instruct the Visual Studio unit test engine to invoke those methods before and after each unit test method is executed.The
_Initand_Closemethods do most of their work by delegating to the implementation of implementation inherited from their base class,BaseTest. -
Right-click on the
BaseTestbase class and click Go To Definition. This will take you to the core implementation of the_Initand_Closemethods. -
Typically, within the
_Init, thelogicalNamevariable is set to a valid I/O resource descriptor or to a valid logical name configured in the IVI Configuration Store. For purposes of this walkthrough, we can leave the value of thelogicalNameas it was set when Nimbus created the unit test project (Acme4321UnitTest), as we will be operating the driver in simulation mode.Modify the
initOptionsvariable to run the driver in simulation mode by changing the value of theSimulateoperation toTrue, as shown below:var initOptions = "QueryInstrStatus=True, Simulate=True, DriverSetup= "; -
From the Build menu, choose Build Acme4321UnitTest.
-
From the Test View, right-click the IAcme4321UnitTest node and choose Run Selection.
The Test Results View opens in the lower portion of the Visual Studio IDE, and shows the status of the unit test methods as they execute. Verify that the
SweepSourceandConfigure_Int32_Boolean_TriggerSourceunit tests passed. -
Return to the Test View and select all 5 unit test classes. Right-click on any one of them and choose Run Selection. This will execute the entire suite of unit test methods that Nimbus has generated for the driver, which includes working code for all of the IVI inherent capabilities.
You should expect the Test Results window to list the following 3 unit test methods as having failed. The Error Message column next to each should indicate that each test failed because the test is not implemented.
WarningInterchangeCheckWarning- Coercion
-
Right-click on the
Warningtest in the Test Results view and select Open Test. This will take you to the location of the Nimbus-generated unit test method for theWarningevent defined on the IVI.NET-definedIIviDriverOperationinterface.Because Nimbus doesn’t know how to appropriately implement a unit test for the
Warningevent, it generates the following boilerplate implementation:[TestMethod]public void Warning(){Assert.Fail("Test not implemented.");}Note that the
CoercionandInterchangeCheckWarningunit test methods are similarly implemented. -
For the purposes of this walkthrough, simply delete the call to
Assert.Failfrom theWarning,CoercionandInterchangeCheckWarningunit test methods. Each of those unit test methods should now be empty. -
In the Test Results view, click the Run button. Because you’ve made a change to the unit test source code, Visual Studio will automatically rebuild the unit test project, and then execute just the 3 unit test methods that failed. They should now pass.
Creating the Help File
Nimbus provides powerful and flexible features for creating driver help files. Help file templates allow complete control over help file styling and content so that custom branding and other styling requirements can easily be incorporated.One of the most compelling aspects of the Nimbus help editing features is that they provide a single place to enter help content that is used in many places. This greatly simplifies driver documentation management. For instance, the Summary field in the Help Editor is used in all of the following places:
- Automatically generated XML documentation files for IntelliSense support in .NET languages, such as C# and Visual Basic.
- Microsoft Help Viewer help content (for use with the Visual Studio).
- The Help 1.0 (.chm) help file (for standalone viewing and viewing in non-Microsoft IDEs).
To enter help content for a method:
Section titled “To enter help content for a method:”-
From the IVI.NET Driver Designer, select the
Configuremethod. -
Click on the Help tab at the bottom of the Item Editor to bring up the Help Editor.
The Summary tab (listed at the top of the Item Editor) should be the active tab.
-
Enter the following in the Summary field:
Configures the device acquisition. -
Click on the Remarks tab. This will activate the standard Visual Studio HTML editor. The HTML editor allows use of any arbitrary HTML formatting tags.
In the HTML editor for the Remarks field, enter the following within the
\<body\>tag that’s already been provided:<p>This method configures the device acquisition.</p><p>Call the <b>Configure</b> method before invoking the acquisition with the <b>Initiate</b> method.</p> -
Click on the Preview tab in the Help Editor to instantly view the newly entered help content. The formatted HTML text entered for the Remarks field is rendered just as it will appear in the compiled driver help file.
Note that Nimbus automatically includes an Instrument Command section on the help page for the method. This feature of driver help files is very useful for end users accustomed to direct SCPI (or other messaging protocol) programming.
-
The layout and styling of the driver help file is completely customizable via Nimbus Help Templates. Nimbus ships with one pre-built help template that mimic the standard help format of Visual Studio.
From Solution Explorer, right-click on the Acme4321Help project and choose Properties. The Template page shows a preview of each type of help page for the currently active help template. You can easily choose another help template from the Available templates combo box.
See the topic Working with Help Templates for a complete discussion of driver help file customization using templates.
-
Finish documenting the
Configuremethod by providing help documentation for its three parameters:-
Click on the numRecords parameter node below the Configure method node in the driver designer.
-
Click on the Help tab in the Item Editor.
-
Enter the following into the Summary tab:
The number of sweeps to perform. -
Repeat the above steps to enter documentation for the
enabledandsourceparameters to theConfiguremethod. Enter arbitrary Summary information for each.
-
-
From Solution Explorer, right-click on the Acme4321Help project and choose Properties.
For the purpose of this walkthrough, check the Help 1.x (.chm) help format, but leave the other options cleared. The options on this page are described in detailed here.
-
From Solution Explorer, right-click on the Acme4321Help project and choose Build. While the build is in progress, the Visual Studio Output window will display the progress of the help project build.
-
Once the build completes, right-click on the Acme4321Help project in the Solution Explorer and select View Help 1.x (.chm). This will open the newly built driver help file in the Help 1.x viewer.
-
In the help viewer, click on the Contents tab and then expand the Getting Started node. Note that several boilerplate help pages have been included in the driver’s help file, which are described in more detail here.
-
Expand the Acme4321 IVI.NET Driver node in the help viewer, then Reference, Driver Hierarchy, and finally IAcme4321. This is where all the dynamically generated help for the main driver interface’s methods, properties and events will appear.
-
Click on the Configure node in the help viewer table of content. Note that the help documentation entered for the Configure method and its parameters using the driver designer appears in the generated help file.
Creating the Driver Installer
The final task in developing a Nimbus IVI.NET driver is creating the driver installer. The IVI.NET specifications impose a number of detailed requirements for IVI driver installers. Nimbus uses Windows Installer XML (WiX) as the underlying technology for building driver installers. The WiX toolset is in widespread use, especially within Microsoft where it is used to produce the installers for such large-scale projects as Microsoft Office, Visual Studio, and SQL Server.WiX installers consist of a series of XML files that get compiled in the Acme4321Setup project. Nimbus manages the XML files for you as you add functionality to your IVI.NET driver. For instance, when you use the help project properties to enable or disable different help formats, the Nimbus-generated driver setup project will automatically update the WiX source XML files to reflect set of help files and shortcuts that should be installed on end-user systems by the driver installer.
Nimbus also provides a powerful and easy-to-use graphical designer for customizing a driver installer, such as for installing example programs or other dependent files outside the control of Nimbus.
To customize the driver installer
Section titled “To customize the driver installer”-
From Solution Explorer, expand the Acme4321Setup project node. Note that several files have already been added to this project:
-
Images*.*
This folder contains icon and graphic files that are used by the driver installer.
-
Internal*.wx?
This folder contains WiX source files that define the required folder structure required for IVI.NET driver installers by the IVI.NET standards, as well as localizable string resources used on driver installer screens.
-
DriverEULA.rtf
The contents of this license agreement file will be displayed on the driver installer screen when the driver installer is run on end-user machines. You must not remove this file, as the installer source code directly references it. It is essentially empty, providing a place for you to enter the specifics of your driver’s end-user license agreement.
-
Readme.txt
A starter template for a standard IVI.NET driver readme file.
-
Setup.wxs
This WiX source file defines the overall layout of the driver installer, and is the file that’s modified by the integrated driver setup designer.
-
-
Double click on Setup.wxs in the Solution Explorer to launch the driver setup designer.
-
The Setup Designer shows the standard IVI.NET folders present on any system with the IVI Shared Components. IVI.NET standard folders that cannot be modified by the driver installer are shown in gray. The Setup Designer also shows the Acme4321 driver folders under which the driver files will be deployed on the target machine.
-
From the Setup Designer tree view, right-click the Examples folder and choose Add and then select Add Folder…
The standard Windows Add Folder Dialog appears.
-
Navigate to a folder on disk with some files and subfolders and click OK. A dialog box titled Select Files to Add will be displayed. Check and uncheck files to be included in the driver installer as desired. Press OK when you’re done.
Note that the selected folder, its files, and any subfolders and files chosen are now displayed in the Setup Designer tree view. This folder structure will be created on the end-user system by the driver installer.
-
Right-click on the Acme4321Setup project and choose Build.
-
When the build has completed, navigate to the
\<solutionFolder\>\build\Debug\x86directory below the driver solution folder and note that an .msi installer package named Acme4321Setup.msi has been created.
Next steps
Section titled “Next steps”This walkthrough has illustrated how to create a simple IVI.NET driver, implement, test and document methods and properties. We have also shown how to create and customize an IVI.NET-compliant driver installer. You might want to explore the following topics:
- Understanding the Nimbus User Interface
- Adding Functionality to an IVI.NET Driver
- Adding Support for Multiple Instrument Models
- Implementing Driver Methods and Properties- State Caching Overview
- Using Per-User Preferences