NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Seq context in multiple executions

Solved!
Go to solution

I just want to add an example of a really easy way to communicate bi-directionally between a sequence and a UI without using station globals or sequence contexts:

 

Basically, post a synchronous (true for the synchronous parameter) UI Message from a step in the sequence, passing, for the ActiveX data parameter, a propertyobject (container) with variables containing all of the information you need to send to the UI as well as places to store information you want back from the UI. The UI can then use the PropertyObject API to access this container and knows that the thread in the execution will be blocked until the UIMessage is acknowledged or freed and therefore knows its access to the data is synchronous with respect to the sequence. After the postUImessage call returns the sequence knows that the UI is done updating the data it passed in so it can get back out any return values it needs.

 

Hope this helps,

-Doug

Message 11 of 16
(2,774 Views)

My application is different from the standard. Unfortunately, is a mix between parallel and batch model, hence I had to modify the process model and the Operator Interface. Let me do a consideration that are beyond the scope of this post: why developing batch and parallel model separately? I do not thing that my application is so strange. TS should offer a sequencial model and a "multi sockets" model that includes both batch and parallel. 

However, in my model I do not run the "UUT Info dialog" of the modelsupport2.dll (also the modelsupport2.dll would deserve some considerations). In this case my Operator Interface must replicate some commands. I would like to use the same approach of the modelsupport2.dll to communicate the commands to TS (it seemed to me the easiest approach). For what I understood about the dll, it enqueues elements into the "DialogRequestQueue" (command + TestSocket) and changes TS variables in each different execution (like ContinueTesting) using the TS_PropertySetValxxx . Both commands should need the sequence context.

See the code below:

 

 ///////////////////////////
     // Stop Button
     ///////////////////////////
     // set continue flag to false
     tsErrChkMsgPopup( TS_PropertySetValBoolean (testSocketData->testSocket,
                &errorInfo, TEST_SOCKET_CONTINUE_TESTING, 0,
                VFALSE));

or

 

 ///////////////////////////
     // OK Button
     ///////////////////////////
     // store serial number
     errChk(TS_SetPropertyToCtrlVal (panel, testSocketData->ctrls[kTSCtrl_SerialNum],
             testSocketData->testSocket,
             TEST_SOCKET_UUT_SERIAL_NUM));
     // change displayed state
     testSocketData->currentState = kTSCState_Running;
     errChk( RefreshTestSocketCtrls(parentPanel, testSocketIndex));
     // tell controlling sequence to continue test socket execution
     errChk( SendRequestToControllingSequence(panelData, CTRL_REQUEST_TEST_SOCKET_CONTINUE, testSocketIndex));
     break;

 

Is the testSocketData->testSocket the sequence context?

What do you thing about this approach?

 

Thanks a lot for your interest.

0 Kudos
Message 12 of 16
(2,757 Views)

What is the UI taking the place of in your architecture? In the models, the dialog is shown by the controlling execution's thread. That thread also owns all of the modeldata, thus there is no synchronization needed to access it. "testSocketData->testSocket" is NOT the sequence context. That is the data structure that stores information about the testsocket. The data structure is ultimately created as a local variable in the controlling execution of the model (the same execution that displays the dialog). See Locals.ModelData.TestSockets[] in the Test UUTs sequence. The elements of that array at runtime are what modelsupport2.dll stores in  testSocketData->testSocket. Every variable in TestStand is a PropertyObject, including, but not limited to, the sequence context.

 

If all you want to do is override the dialogs and substitute your own UI, there is a simpler way. Rather than using any of the code in modelsupport2.dll you can just override it by modifying the process model.

 

In the ParallelModel you can do this as follows:

  1. Add a statement step to the end of the Get Model Options sequence and set its expression to: Parameters.ModelOptions.ParallelModel_ShowUUTDlg = False
  2. Replace the steps in PreUUT and PostUUT with ones that communicate with your UI. In PreUUT all you need to do is decide whether or not to set Parameters.ContinueTesting to false, set Parameters.TestSocket.UUT.SerialNumber to your serial number, and let the execution continue when you are ready to go. In PostUUT you only need to let your UI know what status to show, or do nothing if you don't care about showing the status. There are many ways to do the communication between the PreUUT and PostUUT and your UI. One of the easiest is with UIMessages like I proposed in my earlier post. Whatever way you do this you should make sure the communication is synchronous (i.e. the teststand sequences wait until your UI tells them it's done and they they are ready to go)
  3. You don't need to modify or borrow any code at all from modelsupport2.dll. You can look at it if it helps you to implement 2 above, but you can also do 2 above completely differently than modelsupport2.dll does and as long as you do what I said in 2 above it should work fine.
  4. You don't really even need to modify the process model. Instead of modifying the process model you can override the ModelOptions, PreUUT, and PostUUT callbacks in your client sequence file. Just do the same thing I mentioned in 1 and 2 above in those sequences in your client sequence file instead. There is even an example of doing this that ships with TestStand. Look in <TestStand Public>\Examples\ProcessModels\ParallelModel. There is also an example for the BatchModel to do something similar.

Also, thank you for your feedback. I'm a bit unclear as to what you mean though. Please explain what you mean by a model that includes both batch and parallel. Do you mean running multiple batch model executions in parallel? You might not be aware, but you can already run multiple instance of the batch model at the same time. Do you still want the parallel model UI too? If so you could just make a mainsequence in your client sequence file that uses a sequence call step to launch a batch model set of executions (use single-pass in this case). Another alternative is to just run multiple instance of your executions using the batch model. There is no fixed limit in teststand, other than what your resources will allow, for the number of executions you can create at once.

 

Anyway, hope this information is helpful. Please let me know if you need more information.

-Doug

Message Edited by dug9000 on 01-28-2009 11:05 AM
0 Kudos
Message 13 of 16
(2,748 Views)
Let me answer point by point:
  1. Yes, I did it.
  2. The matter is in your sentence: There are many ways to do the communication between the PreUUT and PostUUT and your UI. One of the easiest is with UIMessages like I proposed in my earlier post. I can use UImessage from TS-->LV but what about LV-->TS? Till now, the only way I can do it for each execution is using StationGlobal. It is a solution, not very elegant. For the other solutions, i.e. queues, I need the sequence context.
  3. I was looking at the modelsupport2.dll just to understand how it can enqueue elements (commands) into the DialogRequestQueue. This is the solution I would like.
  4. You are right. I changed some steps into process model, but I am also using several callbacks.
Basically I have a parallel model with some changes. It creates P parallel executions (P is the number of total TestSockets = DUTs; P=NxM, N=number of parallel, M=number of batch). The client sequence file is always the same, it is a Machine Sequence and it contains several process model callbacks (ModelOptions, PreUUT, PostUUT and so on). Using synchronization steps like notifiers, semaphores, rendezvous I can group executions in batch. I am simulating a Batch execution inside a parallel model without using the "batch synchronization" step type. I.e. PreUUT wait for 4 DUTs of the same fixture (plate) are ready. Then goes ahead only with the execution of this 4 DUT. The main sequence (of the Machine seq) manages the resources sharing them among the 4 DUTs. The main seq also dynamically load the real test sequence that the user selected on the Operator Interface during the ProcessSetUp callback. I am sorry, but it is difficult to explain. You are right when you say: running multiple batch model executions in parallel.

I appreciated very much your suggestions about the bacth /parallel model. I wrote a post about this argument time ago but it was not so profitable. I will deepen this topic because the solution I implemented works but is not very elegant. 

 

Thanks a lot. 
0 Kudos
Message 14 of 16
(2,724 Views)
Solution
Accepted by logatto

Hi logatto,

 

You asked how to communicate LV-->TS with UIMessages. Here is how:

 

  1. Send the UIMessage synchronously (i.e. pass true for the synchronous parameter) at well defined points where you need the sequences to wait for the UI to tell them what to do, such as PreUUT (where you need to set the serial number and tell the execution to continue) and PostUUT (where you need to update the status for the execution in your UI). By sending the UIMessage synchronously, the execution is effectively blocked until the UI is done handling the message (i.e. until the UI acknowledges or closes the handle for the message).
  2. Pass a teststand data variable from the sequence using the ActiveX Data parameter to the PostUIMessage call when posting such a UIMessage. For example in PreUUT you might pass Parameters.TestSocket, or perhaps the Parameters object, or even the sequence context would be ok in this case because the execution is blocked until the UI is done handling the message. Just make sure you don't hold onto the context in the UI and only access it before you allow the execution to continue.
  3. In the UI, when you get the UIMessage do the following before acknowledging or closing the handle to the message: Use the TestStand PropertyObject ActiveX API to access the variable stored in the ActiveX data property of the UIMessage. You can both get and set properties contained within the variable so this is effectively 2 way communication.
  4. There are some limitations to this though, because you can only get one UIMessage from TestStand at a time, it will block all executions that are tracing until you acknowledge or close the handle to the uimessage.Thus you might want to use this in combination with Notifications or other synchronization primitives so you can acknowledge the UIMessage immediately yet have the execution still block on a Notification until the UI tells it to go. Or you could potentially just use synchronization objects, such as queues and notifications, completely instead as both queues and notifications allow passing teststand variables too. Again, there are many ways to do this.

Another issue you bring up is that to use Queues requires a sequence context. This is actually incorrect. You can use queues and other TestStand synchronization primitives without a sequence context. Although the Enqueue and Dequeue methods of the Queue interface take a Sequence Context pointer, you can and should pass a NULL reference (use an uninitialize reference in LabVIEW for this I think) in the case in which you are not accessing them from the code module of an execution. The online help describes this somewhat if you look at the online help for Enqueue and Dequeue for that parameter. You can even create new synchronization objects or access existing ones by name without a sequence context. Use the Engine method Engine.GetSyncManager and the SyncManager API interface to do so (see the online help for more information).

I think I understand what your architecture is now. Certainly it is a good suggestion for us to consider supporting this specific case in a future version. In the meantime you might consider doing the following:

 

  1. Have your UI control the creation of the 4 initial Batch executions rather than using the parallel model for this. Basically when your user initiates things, your UI can explicitly create 4 executions (i.e. Engine.NewExecution) using the Batch model (with testsockets set to 3 in this case) or you could have a root level controlling execution/sequence do this with sequence call steps. That way you can take advantage of the automatic synchronication that the batch model provides (i.e. all UUTs start and stop together) as well as the ability to use batch synchronization.
  2. The tricky part about this will be how you get the information back from and distinguish which testsockets you are dealing with. I think in this case it might be best to use Queues and/or Notifications for the communication and to have a seperate queue or notification for each of the 4 batches. That way you know which batch a dequeue is for based on which queue or notification you get data from. You can even check multiple queues at once using the Queue.DequeueMutiple API. To get the queue creation synchronizated between the execution and the UI you could either do it by name (i.e. name the queues something like "Batch1Queue", "Batch2Queue", etc.)  and just use the Engine.GetSyncManager API from your UI and the step types from the sequences. Or you could pass a reference to the Queue from the sequence to your UI using UIMessages and the activeX data parameter of the UIMessage. Or you could pass the queue into the execution from your UI as an argument when you call Engine.NewExecution.
  3. There are of course a lot more details to work out, but I think this should be doable.

Anyway, hope this is helpful. Let me know if you need more details about any of this.

-Doug

Message Edited by dug9000 on 01-29-2009 11:17 AM
Message Edited by dug9000 on 01-29-2009 11:20 AM
Message 15 of 16
(2,719 Views)

Thanks Dug, I made many steps forward in communication between TS and LV. Now I have to metabolize your numerous suggestions. I need some days to complete the OI. Then I'll be back on the architecture. You gave me some ideas that I would like to deepen. I'll open a new post on "running multiple batch model executions in parallel".

 

Thanks.

 

Logatto. 

0 Kudos
Message 16 of 16
(2,696 Views)