Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx fails to create error when reserved resource is used in timed loop.

When creating a digtial or analog output task with the write function in a while loop, a parallel task of the same type using the same resource is forbidden an creates an error alerting the user that the specified resource is reserved.  This error, however, does not occur when the a timed loop is used in place of a while loop.  I have attached an example VI to illustrate this.  Is this a bug?

Message 1 of 6
(4,315 Views)

Hi Epsilon,

 

This is an interesting find! Thank you very much for the example code, it helped me understand the issue.

 

The first example that is creating the error is showing a race condition. If one of the "write" blocks starts writing before the other is completely closed, you will get this error. If you create flow control in the first diagram (i.e. wire the error out of one of the writes to the error in of the other), you will not get an error because one of the writes is completely finished before the other one begins.

 

Now, in the case of the timed loop, I don't think this would be considered a bug. When I am watching this in highlight execution mode, it seems as though one of the writes finishes and then the error block of the output node of the timed loop (in the top left) executes, leaving enough time to close out the first "write" block before the other one begins. I can ask some of my colleagues to see if this is the actual progression in a timed loop and let you know.

 

Have you tried running this code with your device? What results are you getting?

 

Peter E

Applications Engineer

National Instruments

Peter E
Applications Engineer
National Instruments
0 Kudos
Message 2 of 6
(4,298 Views)

I'll speculate as to why you see this error with a while loop and not with a timed loop.  I believe that LabVIEW will schedule all code within a timed structure to be bound to a single processor/core during execution.  Since both DAQmx Write VI's are a basically single node (call library), these essentially get serialized within the timed loop.  A regular while loop does not have this restriction, so each call to DAQmx Write may get scheduled on different processors/cores, and may end up running in parallel.

 

Hope that helps,

Dan

Message 3 of 6
(4,281 Views)

I believe McDan is on the right track. The timed loop only uses one processor/core and so the DAQmx Write blocks are happening in series where as the while loop with no flow control could be allowing these Write VIs to happen in parallel and therefore gives you error. This is just one of the little nuances of Timed Loops

 

The fix for the while loop would be to code in such a way to make the two Write blocks happen in series. This could be done by wiring the output error of one write VI to the input error of the other as I mentioned previously.

 

I have attached a revised version of the code that handles errors more effectively and also properly starts the DAQ tasks outside the while loop. In both cases this causes a "resources reserved" error because two tasks cannot be performing on the same port/line of a device at the same time.

 

Peter E

Peter E
Applications Engineer
National Instruments
0 Kudos
Message 4 of 6
(4,273 Views)

Thanks for the explanation!

 

So it seems that DAQmx only checks for parallel instances of tasks that access the same resource.  Also it seems that creating two seperate tasks for the same resource generates the exact same pointer, even if one task uses line 0 and the other task uses the whole port.  

 

Forcing the two tasks into the same thread prevents the error in the while loop scenario as well.  I have attached another example VI that shows this.  Interesting stuff!

 

 

0 Kudos
Message 5 of 6
(4,264 Views)

Epsilon,

 

I would recommend you read three topics in the NI-DAQmx Help.  The first topic is "Task State Model" the second is "Implicit State Transitions", and the third is "Explicit Versus Implicit State Transitions".

 

DAQmx represents each DAQ device as a collection of resources.  When a task transitions to the reserved state (which is for your case was done implicitly when you called DAQmx Read), it attempts to reserve each resource that is required for that task to run.  If any other task has currently has that resource reserved, then you'll see resource reservation errors.  Tasks are not aware of other tasks, they simply try to reserve resources.

 

Forcing the two tasks into the same thread (as happened in the timed loop case) serialized the calls to DAQmx Write as previously discussed.  Before DAQmx Write was called, the Task was  in the unverified state.  Calling write caused DAQmx to implicitly transition the task as follows unverified-verified-reserved-committed-running (where data is read), then implicitly transitions the task back to the verified state.  Once this happens, the first task no longer has any resources reserved.  The second task then does the exact same thing.

 

Outside of the timed structure, these two calls to DAQmx Read can happen at the same time.  Essentially, both tasks are still implicitly transitioning through the DAQmx Task State model, however there is now a chance that both tasks may attempt to transition the their state past the 'reserved' state simultaneously.  When this happens, the task which attempts this transition last will get the resource reservation error.  In your new example VI, you've added a data dependency between the two calls to DAQmx Write which forces LabVIEW's compiler to serialize these calls.  This explicitly puts you back in the same situation that the timed structure implicitly caused.

 

Anyway, there's a few more details for you if you're interested.  Hopefully it provides a bit more insight into what DAQmx is doing behind the scenes.

Dan

Message 6 of 6
(4,260 Views)