LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Timer Callback in Labview (RT)

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

 

 

 

 

 

 

 

 

 

 

 

 

 

Message Edited by Jon Hart on 08-22-2008 07:04 AM
0 Kudos
Message 1 of 6
(2,547 Views)
Will this thread be of any help?
0 Kudos
Message 2 of 6
(2,531 Views)

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.

 

 

0 Kudos
Message 3 of 6
(2,526 Views)

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:

  1. Open a reference to the RT FIFO myAsynchQueue (and allow this open to create the queue if it doesn't exist)
  2. Push your timeout and user data into the queue.
  3. Open a reference to asynchWait.vi with the 0x08 value passed into the options parameter. This creates a reentrant clone of the VI, so you have your very own copy that only you can run.
  4. Call the Run VI VI Server method on the reference you just obtained to the reentrant clone. Pass FALSE for Wait Until Done (and TRUE for AutoDisposeRef)
  5. Close your RT FIFO queue reference.

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. 

0 Kudos
Message 4 of 6
(2,518 Views)

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

0 Kudos
Message 5 of 6
(2,514 Views)
Jon,

Perhaps you can start a dynamic VI (with VI Server). Pass the options to
controls on it's panel, and run it. This dynamic VI can do anything when the
time has elapsed, e.g. send a user event, send a value signalling event to a
control, put things on queue of fifo, or trigger an occurence.

If you make the VI reentrant you can start it as often as you like.

I have no idea if this is acceptable on a RT target (it depends on what you
consider real time), but that's how I'd do it.

Regards,

Wiebe.


0 Kudos
Message 6 of 6
(2,511 Views)