Click or drag to resize

Implementing Dynamic Repeated Capabilities

Nimbus supports two types of repeated capabilities -- static repeated capabilities and dynamic repeated capabilities. Static repeated capabilities represent the fixed functionality of the instrument -- such as physical channels on an oscilloscope. These repeated capabilities must be configured at driver development time using the Driver Settings Editor for the repeated capability in question.

Dynamic repeated capabilities are those that cannot be determined at driver development time. Rather, the driver must "discover" by communicating with the instrument what repeated capabilities are present. For example, a driver for a multi-slot digital I/O mainframe has no way to know at driver development time what type and number of digital I/O cards will be plugged into the available mainframe slots.

In order to support dynamic repeated capabilities, Nimbus provides the Add Physical Names and RemovePhysicalNames functions on each repeated-capability derived class. For each repeated capability supported by the driver, Nimbus generates an entry in the repeated capability macro map maintained in the driver project's RepCaps.h file. Each entry in that macro map produces a class definition that matches the name of the repeated capability, and the static Add Physical Names and RemovePhysicalNames funtions can be invoked directly on these generated repeated capability classes.

Physical names can be added or removed from a repeated capability at any point after driver initialization. Often, physical names are added after during the initialization sequence. The code below demonstrates how to add physical names to a repeated capability called Channel.

C++
ViStatus _VI_FUNC acme4321_InitWithOptions(ViRsrc ResourceName, ViBoolean IdQuery, ViBoolean Reset, ViConstString OptionsString, ViSession* Vi)
{
   auto status = VI_SUCCESS;

   status = nrt::InitWithOptions<Acme4321DriverSession>(ResourceName, IdQuery, Reset, OptionsString, Vi);
    ReturnOnError(status);

   if (Reset)
   {
       status = acme_reset(*Vi);
       ReturnOnError(status);
   }

   ReturnOnError(status);

   // Query the instrument for the number of channels
   // 
   long cChannels;
   status = viQueryf(GetVisaSession(Vi), "SYST:CTYP:COUN?\n", "%lg%*t", &cChannels);
   ReturnOnError(status);

   // Note that the AddPhysicalNames function accepts selectors, so it can include ranges and comma-separated lists of 
   // physical names.  Each channel name is of the form "CH[channel]".  We'll add all of the channels in one go by building
   // a selector that includes a range from 1 to the cChannels we queried from the device.
   // 
   auto strSelector = "CH1-CH" + std::to_string(cChannels);
   status = Channel::AddPhysicalNames(Vi, strSelector);

   return status;
}
See Also

Download a complete CHM version of this documentation here.