12-21-2009 05:44 PM
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
12-22-2009
02:35 PM
- last edited on
11-05-2024
01:29 PM
by
Content Cleaner
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.
12-22-2009 03:10 PM - edited 12-22-2009 03:18 PM
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
12-22-2009 06:20 PM
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
12-22-2009 08:36 PM
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...
12-23-2009 06:54 AM
"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...
12-23-2009 07:02 AM
Hi,
You may have to use a different lib (Synchronization Server API Reference).
Regards
Ray Farmer
12-23-2009
10:21 AM
- last edited on
11-05-2024
01:30 PM
by
Content Cleaner
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.
12-23-2009 11:43 AM
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
12-23-2009 02:15 PM
The instrument driver for the synchronization manager is tssync.fp and is located in the same place tsapicvi.fp.
Hope this helps,
-Doug