IVI State Caching Mechanism
When you enable the state caching mechanism, the IVI Engine maintains a software copy of the current instrument setting for each attribute. If the IVI Engine determines that the cache value accurately reflects the state of the instrument, it considers the cache value to be valid. If state caching is disabled or the IVI Engine determines that the cache value does not accurately reflect the state of the instrument, it considers the cache value to be invalid.
When you call one of the Ivi_GetAttribute functions to query the current setting for an attribute and the cache value for that attribute is invalid, the IVI Engine has the driver perform instrument I/O to obtain the setting, by invoking the read callback for the attribute. After the read callback obtains the current setting, the IVI Engine stores the value in the cache, marks the cache as valid, and returns the value to the caller. If the cache value is already valid, the IVI Engine returns the cache value to the caller immediately.
When you call one of the Ivi_SetAttribute functions to specify a new setting for an attribute and the cache value for the attribute is invalid or different than the value you specify, the IVI Engine invokes the write callback for the attribute, which has the driver send the new setting for the instrument. If the write callback successfully modifies the instrument setting, the IVI Engine stores the new value in the cache and marks the cache as valid.
Initial Instrument State
The IVI state caching mechanism makes no assumptions about the initial state of an instrument. When the driver creates attributes during the initialization of an IVI session, the IVI Engine marks the attribute cache values as invalid. Thus, the first call to an Ivi_GetAttribute or Ivi_SetAttribute function for an instrument attribute causes the driver to perform instrument I/O.
It is the user's responsibility to set the instrument to a known state. Typically, the user sets the state by calling the instrument driver high-level configuration functions.
Special Cases
Instrument command sets do not always map perfectly onto the state caching model. In such cases, you must take special actions to ensure that the state caching mechanism works properly given the behavior of a particular instrument. The following sections describe four possible situations.
Changing the Value of One Attribute Invalidates Another
In many cases, changing the value of one attribute causes the setting of another attribute in the instrument to change. For example, changing the measurement function in a DMM can change the range setting. In this case, the specific driver must indicate to the IVI Engine that setting the first attribute invalidates the second attribute. The specific driver can notify the IVI Engine of this relationship by calling Ivi_AddAttributeInvalidation. Whenever a call to an Ivi_SetAttribute function changes the value of the first attribute, the IVI Engine marks the cache value of the second attribute as invalid. For each IVI session, the IVI Engine maintains a list of invalidation relationships.
The specific driver also can call Ivi_InvalidateAttribute to invalidate the cache value of an attribute directly.
In some cases, you might think you can determine the new value of the second attribute and set its cache value. However, it is better to invalidate the second attribute. Any assumption you make about the new state of the second attribute depends on instrument behavior that might change in future revisions of the instrument. As the Initial Instrument State section explains, it is the user's responsibility to set the instrument to a known state.
Two Attributes Invalidate Each Other
In rare cases, changing the value of one instrument setting can affect another instrument setting, and changing the value of the second instrument setting can affect the first. For example, changing the measurement range in a DMM commonly affects the resolution setting. If changing the resolution setting can change the measurement range, the invalidation relationship is two-way.
The proper way to handle this situation is to impose a one-way invalidation model in the instrument driver. Identify one attribute as dominant and the other as subordinate. Call Ivi_AddAttributeInvalidation to notify the IVI Engine that changing the value of the dominant attribute invalidates the subordinate attribute. Range check and coerce values for the subordinate attribute based on the current setting of the dominant attribute. In the previous example, select the measurement range as the dominant attribute. Range check and coerce the resolution attribute so that you cannot set the resolution to a value that would cause the instrument to modify the measurement range setting.
Setting or Getting the Values of Two Attributes in One Command
Some instruments have command sets that force the driver to set or get two attributes at once. The driver cannot set or get the value of one attribute without also setting or getting the value of another. In this case, the read callback for each coupled attribute must record the value it obtained for the other attribute. The read callback can record the value it obtained for the other attribute by calling the appropriate Ivi_SetAttribute function and passing IVI_VAL_SET_CACHE_ONLY as the optionFlags parameter.
The write callbacks can be more difficult to handle. Generally, one of the coupled attributes is dominant. If so, the write callback for the dominant attribute must calculate the default value of the subordinate attribute, include the value in the command string it sends to the instrument, and call the appropriate Ivi_SetAttribute function with the IVI_VAL_SET_CACHE_ONLY flag to cache the new value of the subordinate attribute. The write callback for the subordinate attribute must call the Ivi_GetAttribute function to obtain the current value of the dominant attribute and use its value in the command string. When a high-level driver function wants to set the two attributes, it must set the dominant attribute first. Handling such order dependencies while minimizing instrument I/O is one of the benefits that the high-level driver functions provide to application programs.
Instrument Coerces Values
In some cases, an instrument accepts a range of values for an attribute but coerces them into discrete settings. For example, a DMM might have three maximum reading ranges, 10.0, 100.0, and 1,000.0, but accept any value from 1.0 to 1,000.0. If you set the maximum reading range to 50.0, the instrument coerces the value to 100.0. In responding to a query, the instrument returns 100.0. If, after you set the attribute to 50.0, the IVI Engine stores 50.0 in the cache, the cache does not accurately reflect the state of the instrument. Instead, the IVI Engine must store 100.0 in the cache.
Thus, state caching requires the driver to coerce the value in software before sending it to the instrument. Requiring coercion is especially important for drivers that comply with a standard class definition. To handle any specific driver within a class, the class definition must allow for a continuous range of values. Each specific driver must coerce the range of values into the discrete settings the instrument uses.
The driver can coerce the range of values by using a coerce callback. The easiest way to use a coerce callback is to create a coerced range table for the attribute. The IVI Engine ensures that attributes with coerced range tables use a default coerce callback.
In rare instances, an instrument might coerce a value using an algorithm that is undocumented or too complicated to encapsulate in a range table or a coerce callback. You can let the instrument coerce the value and still retain much of the benefits of state caching by using the IVI_VAL_COERCEABLE_ONLY_BY_INSTR flag.
Enabling and Disabling State Caching
The user can enable or disable the state caching mechanism for an entire IVI session by setting the IVI_ATTR_CACHE attribute. Nevertheless, a specific instrument driver can override the user's choice on an attribute-by-attribute basis. The driver can set the IVI_VAL_NEVER_CACHE flag for an attribute to prevent the IVI Engine from using the cache. The driver can set the IVI_VAL_ALWAYS_CACHE flag for an attribute to force the IVI Engine to always use the cache value, if valid, regardless of the state of IVI_ATTR_CACHE.