212 lines
8.6 KiB
C
212 lines
8.6 KiB
C
/********************************************************************/
|
|
/* This example demonstrates VISA locking */
|
|
/* */
|
|
/* In VISA, applications can open multiple sessions to the same */
|
|
/* resource simultaneously and access that resource through these */
|
|
/* different sessions concurrently. */
|
|
/* In some cases, an application may need to restrict other */
|
|
/* sessions from accessing that resource. */
|
|
/* For example, an application may need to execute a write and a */
|
|
/* read operation as an atomic operation so that no other */
|
|
/* operations intervene between the write and read operations. */
|
|
/* If another application or even this same application were to */
|
|
/* perform another write between this first write and read, then it */
|
|
/* could put the instrument in an unstable state. */
|
|
/* This is where locking becomes convenient. The application can */
|
|
/* lock the resource before invoking the write operation and unlock */
|
|
/* it after the read operation, to execute them as a single step. */
|
|
/* This prevents other applications from accessing the resource */
|
|
/* and prevents possible contention. VISA defines locking */
|
|
/* to restrict accesses to resources for such special circumstances.*/
|
|
/* */
|
|
/* The VISA locking mechanism enforces arbitration of accesses to */
|
|
/* resources on an individual basis. If a session locks a resource, */
|
|
/* operations invoked by other sessions are returned with an error. */
|
|
/* */
|
|
/* This VI opens two sessions to an instrument and locks the first */
|
|
/* session. The first session then writes the String to Write to */
|
|
/* the instrument and reads a response of the desired length. */
|
|
/* */
|
|
/* The second session tries to do the same task but will not */
|
|
/* succeed unless the first session is unlocked. */
|
|
/* */
|
|
/* The general flow of the code is */
|
|
/* Open Resource Manager */
|
|
/* Open 2 VISA sessions to an instrument */
|
|
/* Lock the first session */
|
|
/* Read and write to that instrument using the first session */
|
|
/* Unlock the first session */
|
|
/* Now read and write to the instrument with the second session*/
|
|
/* Close the VISA Sessions */
|
|
/********************************************************************/
|
|
|
|
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
|
/* Functions like strcpy are technically not secure because they do */
|
|
/* not contain a 'length'. But we disable this warning for the VISA */
|
|
/* examples since we never copy more than the actual buffer size. */
|
|
#define _CRT_SECURE_NO_DEPRECATE
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "visa.h"
|
|
|
|
static ViSession defaultRM;
|
|
static ViSession instr1, instr2;
|
|
static ViUInt32 retCount;
|
|
static ViUInt32 writeCount;
|
|
static ViStatus status;
|
|
static unsigned char buffer[100];
|
|
static int cchar;
|
|
static char stringinput[512];
|
|
|
|
|
|
int main (void)
|
|
{
|
|
/*
|
|
* First we must call viOpenDefaultRM to get the resource manager
|
|
* handle. We will store this handle in defaultRM.
|
|
*/
|
|
status=viOpenDefaultRM (&defaultRM);
|
|
if (status < VI_SUCCESS)
|
|
{
|
|
printf("Could not open a session to the VISA Resource Manager!\n");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
/*
|
|
* Now we will open a session to a GPIB instrument at address 2.
|
|
* We must use the handle from viOpenDefaultRM and we must
|
|
* also use a string that indicates which instrument to open. This
|
|
* is called the instrument descriptor. The format for this string
|
|
* can be found in the function panel by right clicking on the
|
|
* description parameter. After opening a session to the
|
|
* device, we will get a handle to the instrument which we
|
|
* will use in later Visa functions. The two parameters in this
|
|
* function which are reserved for future functionality.
|
|
* These two parameters are given the value VI_NULL.
|
|
*/
|
|
status = viOpen (defaultRM, "GPIB0::2::INSTR", VI_NULL, VI_NULL, &instr1);
|
|
if (status < VI_SUCCESS)
|
|
{
|
|
printf ("Cannot open a session to the device.\n");
|
|
goto Close;
|
|
}
|
|
|
|
/*
|
|
* Now we will open another session to a GPIB instrument at address 2.
|
|
*/
|
|
status = viOpen (defaultRM, "GPIB0::2::INSTR", VI_NULL, VI_NULL, &instr2);
|
|
if (status < VI_SUCCESS)
|
|
{
|
|
printf ("Cannot open a second session to the device.\n");
|
|
goto Close;
|
|
}
|
|
|
|
/*
|
|
* Now we will lock the first session to the resource using the
|
|
* viLock function. Notice that the locking command takes a parameter
|
|
* which can be set to VI_EXCLUSIVE_LOCK or VI_SHARED_LOCK. The exclusive
|
|
* lock will only let that session access the device until the
|
|
* lock is released. The shared locking option uses the last two parameters
|
|
* which are set to VI_NULL for the exclusive lock. The first of these
|
|
* is a requested access key for the shared lock. The last parameter is
|
|
* a return value with the actual key assigned to the lock. If the shared
|
|
* lock is used the return actual key value can be used by another session
|
|
* for the actual key parameter to gain access to the locked resource.
|
|
* Please refer to the NI-VISA User Manual for more information.
|
|
*/
|
|
status = viLock (instr1, VI_EXCLUSIVE_LOCK, VI_TMO_IMMEDIATE, VI_NULL, VI_NULL);
|
|
if (status < VI_SUCCESS)
|
|
{
|
|
printf("Error locking the session");
|
|
goto Close;
|
|
}
|
|
|
|
|
|
/*
|
|
* Now we will write the string "*IDN?\n" to the device and read back the
|
|
* Response from the session that obtained a lock on the resource
|
|
*/
|
|
strcpy(stringinput,"*IDN?\n");
|
|
status = viWrite (instr1, (ViBuf)stringinput, (ViUInt32)strlen(stringinput), &writeCount);
|
|
if (status < VI_SUCCESS)
|
|
{
|
|
printf("Error writing to the device\n");
|
|
goto Close;
|
|
}
|
|
|
|
/*
|
|
* Now we will attempt to read back a response from the device to
|
|
* the identification query that was sent. We will use the viRead
|
|
* function to acquire the data. We will try to read back 100 bytes.
|
|
* After the data has been read the response is displayed.
|
|
*/
|
|
status = viRead (instr1, buffer, 100, &retCount);
|
|
if (status < VI_SUCCESS)
|
|
{
|
|
printf("Error reading a response from the device\n");
|
|
goto Close;
|
|
}
|
|
else
|
|
{
|
|
printf("\nData read: %*s\n",retCount,buffer);
|
|
}
|
|
|
|
/*
|
|
* Now we will ask the user if they want to unlock the resource.
|
|
* Then we will try the same operations with the second session. If the
|
|
* resource is not unlocked these operations will fail as would any attempts
|
|
* to modify global attributes by the second session.
|
|
*/
|
|
printf("Do you wish to unlock the resource so the second session can also access it(y/n)?\n");
|
|
cchar = getchar ();
|
|
if (cchar == 'y' || cchar == 'Y')
|
|
{
|
|
status = viUnlock (instr1);
|
|
if (status < VI_SUCCESS)
|
|
{
|
|
printf("Error unlocking the resource\n");
|
|
goto Close;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Now we will attempt the same read and write sequence we attempted with the first
|
|
* session. If the lock was not removed this will fail
|
|
*/
|
|
status = viWrite (instr2, (ViBuf)stringinput, (ViUInt32)strlen(stringinput), &writeCount);
|
|
if (status == VI_ERROR_RSRC_LOCKED)
|
|
{
|
|
printf("The resource is locked you can't write to it!\n");
|
|
}
|
|
|
|
/*
|
|
* Now we will attempt to read back a response from the device to
|
|
* the identification query that was sent. We will use the viRead
|
|
* function to acquire the data. We will try to read back 100 bytes.
|
|
* After the data has been read the response is displayed.
|
|
*/
|
|
status = viRead (instr2, buffer, 100, &retCount);
|
|
if (status == VI_ERROR_RSRC_LOCKED)
|
|
{
|
|
printf("The resource is still locked you can't read from it!\n");
|
|
}
|
|
else
|
|
{
|
|
printf("\nData read: %*s\n",retCount,buffer);
|
|
}
|
|
|
|
Close:
|
|
status = viClose(instr1);
|
|
status = viClose(instr2);
|
|
status = viClose(defaultRM);
|
|
printf("Finished closing sessions.\nHit enter to continue.\n");
|
|
fflush(stdin);
|
|
getchar();
|
|
|
|
return 0;
|
|
}
|