08-22-2008 07:02 AM - edited 08-22-2008 07:04 AM
Hi,
Could somebody enlighten me please. I need to implement an callback mechanism in Labview on a cRIO RT platform (VxWorks). Our project makes extensive use of asynchrounous statechart behaviour (provided by the NI statechart module) and being able to generate a callback is essential given the event driven nature of the system.
I have found many forum threads about registering callback functions for ActiveX DLLs but this is not an option for us (unless someone wants to implement COM/OLE for a VxWorks platform!) so please don't reply with that "solution".
So here is what I need (and it isn't much to ask really)
To be able to call a StartTimer.vi specifying a wait period and a user defined integer parameter. This call MUST be non blocking (returns immediately).
Carry on with other processing...
...
...
After the specified time elapses, an event is generated (passing the value of the user data). it would be ok if separate thread had to be set up to receive these events ( a la WaitForSingle/MultipleObject in the Windows API )
Here is what I have tried so far:
My StartTimer routine just pushes the timer period and the value into an RTFIFO.
Another thread waits on RTFIFO messages. When it gets one it pops it off the FIFO and waits for the specified time before performing the task desired.
The drawback is that all callback events are sequentially queued and thus subsequent delays must wait for previous ones to finish. This is unacceptable in a RT system.
Regards
Jon
08-22-2008 08:09 AM
08-22-2008 08:59 AM
muks,
Thanks for posting but that thread (no pun intended) is really about thread synchronisation.
My problem is to do with how to set up a scheduled timer without blocking a thread.
08-22-2008 10:55 AM
I brainstormed this for a few minutes with one of my fellow developers and here is the general scheme we came up with (I imagine others have come up with it too).
Create a reentrant VI asynchWait.vi . This VI begins by opening a reference to a named RT FIFO (myAsynchQueue) and dequeing one element. The type of data on the fifo is a cluster with your time to wait and your user data.
After the dequeue, the VI waits the specified time and then does whatever you want it to do with the user data (fire an event). It then closes the reference to its RT FIFO.
Now, how do you use this VI? Your caller VI does the following:
With this you should basically be able to asynchronously run any code after a specified timeout period. And what happens if two people try to do it at the same time? They both share the same queue, but the two different reentrant clones each pull of one queue element and wait separately. Hopefully the jitter that might come from high contention on the same queue is acceptable. We would have to think of other approaches if not.
Let us know how that works, or if an example would be helpful.
08-22-2008 11:16 AM
aggieNick,
Thanks for your much considered answer ( you clearly understand what the issue is ). I will try your scheme out next week (am meant to be on vacation!) and let you know if I should ship your cigar...
Regards
Jon
08-22-2008 11:40 AM