LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

interrupt on delay

I'm writing a burn-in test, so I put a Delay() function, but I need to interrupt and stop it by a "command button" during delay wait state. So I got stuck on wirting CVI code for this interrupt process.
What would be a good practice of writing this type of code? I tred to take a long delay and put a "for- loop" and delay one second inside. This take some computer resources and I still don't know when the button was pressed to stop it. Can someone tell me the trick of how do I recongnize the command button was pressed to stop a delay loop? Thanks.
0 Kudos
Message 1 of 9
(4,412 Views)

Well, it depends on how often you must check your process during test execution.  In any case Delay () is not a good function to use in this case.

 

If you must pay the maximum attention to the process being executed, you can embed it in a for loop without the Delay (); in the loop you must insert a ProcessSystemEvents () to permit processing of other controls' callbacks so that pressing the Stop button is got. In the Stop button callback you can rise a global flag that is tested in the test loop and causes its end.

In the same approach, you could use a toggle button as the Stop and GetCtrlVal of this button inside the loop (always after a ProcessSystemEvent is called), this way preventing the use of a separate callback and a global variable.

 

If you can survey the process at a lower degree of detail, you can use a timer fired a few times per second, accumulating into the timer callback eventData2 values (time passed from previous execution of the callback). In this approach, the timer callback could be structured as a state machine based on a global "state" variable that describes what the equipment is doing: idle, ready for test, test execution, test stopping (this last in case some long process is necessary to end the test). In this approach, the system is free to test the stop button without any other action from you; in the stop button callback you must manipulate the global state variable and initiate test stopping.

 

Hope this helps

Roberto



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 2 of 9
(4,401 Views)
NI has claimed in the past that their Delay() function includes a process events call, but they haven't given any detail as to how often it's called.    I'll believe it when I see the code.  This question comes up time and again. 

In Microsoft's Windowing paradigm, this problem is solved with "user interface threads" (compared to "regular" threads) that automagically know to check for and handle Windows messages (i.e. user interface events).

I usually use my own "sleep with GUI" function to solve this.  As the previous response indicated, you can get whatever granularity is appropriate for your application between ProcessEvents() calls.  I use the Win32 API "SleepEx" function, as you then have more certainty that the thread is asleep/active when you think it is compared to the CVI Delay() function.  It's not going to be perfect - you will consume some resources to periodically wake the thread and process events, but that's way better than a busy wait or delaying the event unreasonably.

I've also solved the problem of guaranteeing a timely response to an important control (typically an "Abort" button) by using a separate, small panel/control running on a dedicated, high priority thread whose only purpose is to check the state of the Abort button.  However, any code you invoke in response to the control must be thread safe - and I've had trouble with some of NI's supposedly thread-safe libraries, in particular NI DAQ.  NI claims to have cleaned up these issues in the more recent NI DAQ releases.




0 Kudos
Message 3 of 9
(4,383 Views)

To clarify: the Delay function has never processed UI events. The Delay function causes your thread to sleep in chunks of time up until the total time has expired. Internally, it does not call ProcessSystemEvents, or GetUserEvent, or any similar function.

I hope we have never given the impression that CVI callbacks would be called during a call to Delay. To ensure that callbacks would be called, you will have to essentially do a "sleep with GUI" loop as you describe.

Luis
NI

0 Kudos
Message 4 of 9
(4,360 Views)
Thanks Luis.

I would say it's often difficult to anticipate just what an NI library routine or the runtime engine will do, especially when multi-threading.  I use a Win3 API call whenever I can - the semantics are well known, and at the end of the day, the runtime engine is executing on an OS thread (or threads - it looks to me like the RTE's multi-threaded, even if the app is "single threaded").

It would help if there were a better depiction of the RTE and thread-related library routine behavior, as it does matter at times.
0 Kudos
Message 5 of 9
(4,345 Views)
The RTE itself is not multithreaded. It runs on whichever threads the user's application creates. However, depending on what the application is doing, threads might unexpectedly be created -- when using ActiveX controls, for example -- which will then show up in the debugger.
 
I agree with you that it can be frustrating to not know what exactly libraries that we depend on are doing Smiley Wink I'll point you to two pieces of documentation that you might have already found, but in case you haven't, you might find of use:
 
1. In the CVI online help, browse to "Library Reference>>User Interface Library>>Multithreading>>Different Approaches to Multithreaded User Interface Programming".
 
2. I'm not sure which version of CVI you have, but in all likelihood, you have a Bookshelf item that you can access from the CVI Help menu. When you click that item, you should be looking at a PDF that includes links to other PDFs. These consist of topics which we wanted to discuss more in-depth than the online help format allows. There is a topic in particular, "Multithreading in LabWindows/CVI" that you might find useful, if you haven't seen it before.
 
Luis
0 Kudos
Message 6 of 9
(4,325 Views)

Thanks for the good info.

We happen to have a dual processor hyperthreaded Xeon PC running XP Pro (OS treats as four CPU's).  I've noticed that a nominally single-threaded CVI app reports four threads in this situation.  Do you know what's happening here?   Is the CVI RTE creating a thread for execution on each CPU?  Do we know that all the CVI libraries will work properly in such a case? 

Hayes

0 Kudos
Message 7 of 9
(4,185 Views)
Hayes,

I don't have a dual processor PC handy right now,where I could test this, but I don't think that you automatically get extra threads just because you are running in a dual processor. Or in hyperthreaded mode, for that matter. The only connection in CVI between the number of CPUs and number of threads, is that the maximum number of threads in a thread pool depends on the number of CPUs, but this would only be a factor for you if you were scheduling threads yourself using the multithreading functions of the CVI Utility Library.

All of the CVI libraries are multithread-safe, so you don't really have to worry too much about this, but if it's puzzling you, and you'd like to investigate this some more, you can put some breakpoints in different  parts of your code, and check the number of threads each time. That should allow you to figure out when those extra threads are being created. I'd start with the very top of your main() function, and go from there.

Luis
0 Kudos
Message 8 of 9
(4,180 Views)
Luis -
 
Thanks for the feedback.
 
I seem to recall reading somewhere that the CVI RTE creates a thread for each of a multi-processor environment.
 
The app in question does have a Word 2000 ActiveX interface, so perhaps the threads are coming from there.  I wonder if an ActiveX thread ever terminates or if it stays alive until the process finishes.  I'd think they would self terminate, otherwise the process may not terminate so long as as a thread is active.
 
Hayes
0 Kudos
Message 9 of 9
(4,175 Views)