NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Use TestStand synchronization (mutex) from LabWindows/CVI

I am having difficulty using the TestStand SyncManager in LabWindows.

 

I'd like to use a mutex in my TestStand sequence and in a TestStand UI Monitoring application in case the same GPIB instrument is accessed at the same time.

 

Is there a simple example which shows how to use a shared TestStand mutex in CVI?

 

Here's what I have so far:

 

 LPUNKNOWN tempActiveXRef;
 CAObjHandle SyncManagerObj;
 char* MutexName = "*GPIBMutex";
 
 hr = TS_EngineGetSyncManager(gMainWindow.engine, &errInfo,"*GPIBMutex",&tempActiveXRef);

 

 tsErrChkMsgPopup( CA_CreateObjHandleFromInterface (&tempActiveXRef, &IID_IDispatch, 1,
            LOCALE_NEUTRAL, 0, 0, &SyncManagerObj));
 
 hr = TS_StepGetMutexNameOrRefExpr(SyncManagerObj,&errInfo, &MutexName);
 hr = TS_StepSetUseMutex(SyncManagerObj,&errInfo, VTRUE);

 

But CVI bombs at the CA_CreateObjHandleFromInterface call probably because I'm using 'IID_IDispatch' - but what should it be?

Many Thanks!

 

Ronnie

TestStand 4.2.1, LabVIEW 2009, LabWindows/CVI 2009
0 Kudos
Message 1 of 11
(4,635 Views)

Believer,

 

So in cvi the function name tells us what object we need  so whe you call TS_StepGetMutexNameOrRefExpr we are saying that we are using the teststand library (TS_) we are working with the step object (Step) - this is the object handle you need to pass into the cvi function. Then we are getting a property (Get) and the name of that property is GetMutexNameOrRefExp ( https://www.ni.com/docs/en-US/bundle/teststand-api-reference/page/tsapiref/steptype-mutexnameorrefex... ) . Based on that and working backwards we need to get an object handle to the step that aquires or releases the mutex.

 

So since we already have a handle to the engine we can walk down the ladder and get the sequence file, from there we can get the sequence and then the step you want to manipulate. Once you have a handle to that step you can pass it into TS_StepGetMutexNameOrRefExpr.

 

I always stress modularity in TestStand designs. So we want to be able to make every individual piece of our UI and code modules re-usable for as many different tests as possible. Instead of hard-coding syncronization into a step or a UI, if at all possible i strongly recommend to keep it all inside of TestStand (in a sequence). That makes it much easier to change the functionality of your teststation and much easier to debug an individual component, as well as having the added benefit of making reusable code.

Richard S -- National Instruments -- (former) Applications Engineer -- Data Acquisition with TestStand
0 Kudos
Message 2 of 11
(4,613 Views)

Richard S - Thanks for your response but I don't think you understood my post.

 

Imagine I have a TestStand sequence which accesses a GPIB instrument.

I also have an application which constantly checks the status of that instrument.

They need to be able to run at the same time - hence the need for a mutex to avoid conflict.

 

Looking at other posts the recommendation is to use the TestStand SyncManager functions in the sequence, and then access the same mutex via the engine in any other application.

 

So - I have put the step locks (create and release early) in my TestStand sequence around the steps I want to safeguard.

 

Now I'm ready to use the same mutex in my CVI UI which accesses the same instrument.

It is a TestStand UI but the important thing is that I have access to the Engine & Sync Manager.

So I'm looking at the SyncManager functions in the 4.2 help and I don't see much similarity.

 

For example I can't find the EarlyUnlockMutexEx function.

 

Clearly my attempt in the first post is way off the mark - hence my request for a simple example.

 

Hope this makes it a bit clearer.

 

Thanks,

 

Ronnie

 

 

 

Message Edited by Believer on 12-22-2009 01:18 PM
TestStand 4.2.1, LabVIEW 2009, LabWindows/CVI 2009
0 Kudos
Message 3 of 11
(4,609 Views)

You need to call Engine.GetSyncManager(). Then use SyncManager.CreateMutex() to create or get the existing mutex. The use Mutex.LockMutex or Mutex.LockMutexGroup to lock the mutex. These two methods return an AutoReleaser object. The AutoReleaser object unlocks the mutex when it's destroyed (i.e. when its last reference is released) or when you call EarlyReleaseEx on it. See the online help for these APIs for more information.

 

Hope this helps,

-Doug

0 Kudos
Message 4 of 11
(4,591 Views)

Doug,

 

I am calling  Engine.GetSyncManager() ...  (please read my first post)

 

My problem is that in CVI there seem to be only 5 functions that deal with the Mutex (unless the Find is not finding them)

 

  TS_StepGetMutexNameOrRefExpr(,,);
  TS_StepGetUseMutex(,,);
  TS_StepSetMutexNameOrRefExpr(,,);
  TS_StepSetUseMutex(,,);
  TS_StepTypeGetMutexNameOrRefExpr(,,);

 

There is no SyncManager.CreateMutex()  nor  Mutex.LockMutex. I can also find no EarlyReleaseEx function.

 

All I want is a few lines of LabWindows CVI code to show the process of obtaining the lock and then doing an early release...

 

 

 

 

 

 

TestStand 4.2.1, LabVIEW 2009, LabWindows/CVI 2009
0 Kudos
Message 5 of 11
(4,585 Views)

 

"There is no SyncManager.CreateMutex()  nor  Mutex.LockMutex. I can also find no EarlyReleaseEx function."

 

Obviously I mean that I cannot find a LabWindows equivalent of these...

 

TestStand 4.2.1, LabVIEW 2009, LabWindows/CVI 2009
0 Kudos
Message 6 of 11
(4,573 Views)

Hi,

 

You may have to use a different lib (Synchronization Server API Reference).

 

Regards

Ray Farmer

Regards
Ray Farmer
0 Kudos
Message 7 of 11
(4,570 Views)

 You can use the CreateMutex method. https://www.ni.com/docs/en-US/bundle/teststand-api-reference/page/tssyncserver/syncmanager-createmut...

 

Based on your use case, if I understood it correctly, you have a sequence that is using a GPIB instrument and another program that is asyncronously querying that instrument. If I was to start this project from scratch, I would first run a sequence in a new thread, this thread would look something like this

 

While

     Lock

     Action (query gpib instrument)
     Unlock

     Wait

end

 

That way it will constantly be checking your gpib instrument asyncronously while your test is running, then anytime in your sequence you want to call the GPIB instrument put lock steps around it. The lock steps will ensure that you are never accessing the instrument at the same time. That way you 1) Can run your code outside of TestStand (since you won't need the execution references, and 2) Keep all buisness logic and flow control at the TestStand level, so that you can easily change the functionality without having to dig into code modules. There may be other aspects of your project that I don't understand, so this may not work for you. But that is how I would syncronize between my sequence and a constantly running task. 

 

 

Richard S -- National Instruments -- (former) Applications Engineer -- Data Acquisition with TestStand
0 Kudos
Message 8 of 11
(4,560 Views)

Ray - a glimmer of hope from your post! I just need to find the library and figure it out.

It seems that the CVI implementation of the TS API is not complete.

Thanks,

Ronnie

TestStand 4.2.1, LabVIEW 2009, LabWindows/CVI 2009
0 Kudos
Message 9 of 11
(4,553 Views)

The instrument driver for the synchronization manager is tssync.fp and is located in the same place tsapicvi.fp.

 

Hope this helps,

-Doug

0 Kudos
Message 10 of 11
(4,546 Views)