LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Intermittent 1097 Errors (MPUSBAPI.dll)

Hi All,

I have an application that uses the MPUSBAPI.dll to communicate with a micro controller through USB. My application is calling the MPUSBRead and MPUSBWrite functions several times a second successfully, but will occasionally get into a state where some of the DLL calls return error 1097. Once this starts, it usually cannot be recovered from without a software restart. I came across the post linked below (see message 6), where rolfk indicates that the most frequent cause of error 1097 is an incorrect call setup. I would not have guessed that as the DLL works 95% of the time, but I could certainly be wrong. The write function is the one to return the error the majority of the time. 

 

I am wondering a couple of things -  have others used this DLL successfully? Without intermittent errors? Second, would I be better off trying to setup my device for using VISA USB? 

 

My Call Setup for the MPUSBWrite method of the DLL is as follows 

-Function-

Calling Convention - C

Run in any thread

-Parameters- 

return type - U32

Handle - U32, pass by value

Data - U8 Array, Array Data pointer, no min size set

Length to Send - U32, pass by value (Length of Data array converted to U32)

Actual Length - U32, pointer to value, constant of 0 written to CLF.

Timeout(ms) - U32, Pass by Value

 

 

https://forums.ni.com/t5/LabVIEW/Error-1097-calling-dll/td-p/1662080

0 Kudos
Message 1 of 14
(3,578 Views)

Link to the header file below - I am wondering if I should be using Instance Data Pointer as the type for Handle.

 

 

 

https://github.com/mentatpsi/Microchip/blob/master/USB/Tools/MCHPUSB%20Custom%20Driver/Mpusbapi/Dll/...

0 Kudos
Message 2 of 14
(3,563 Views)

@paul.r wrote:

Link to the header file below - I am wondering if I should be using Instance Data Pointer as the type for Handle.

 


Nooooooo! It is a pointer sized integer!

 

Just because the Write function reports the error doesn't mean that it is the one which is configured wrong. Buffer overflow errors will corrupt memory that can crash other code and cause errors elsewhere.

 

Without seeing the VIs for this driver I would guess that it makes the standard error of many LabVIEW programmers who try to interface to a DLL.

The Read function needs to pass a buffer to the DLL function that is as big as it asks the function to return data for. One byte off is enough to cause trouble.

The Write function usually does not have this error since you pass in a buffer of data to write out and therefore it is very hard to make this buffer to small.

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 14
(3,558 Views)

Thanks for the feedback! I do initialize an array the size of the read length, and pass that into the data field on reads. 

 

Should I be passing the pointer, rather than the value for the handle?CodeSnippet.png

0 Kudos
Message 4 of 14
(3,546 Views)

@paul.r wrote:

 

Should I be passing the pointer, rather than the value for the handle?CodeSnippet.png


No! Make the datatype a pointer sized unsigned integer instead of a 32 bit unsigned integer! And use an unsigned 64 bit integer control on the front panel for passing the handle around. The read function in the snippet looks ok so far.

Are there other functions that you call that require a buffer to be passed in?

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 14
(3,535 Views)

Again, thanks for the feedback. I will make that update, and see if I see any different behavior. Unfortunately, because the problem is intermittent, it will be difficult to know if that was the root cause. 

 

And nope - the only other functions in the DLL I am calling are the open and close (in addition to the write).

 Open Function.png

 

0 Kudos
Message 6 of 14
(3,530 Views)

One other question - I updated the handle data type, should I being passing the value or a pointer to the value?

Thanks!

0 Kudos
Message 7 of 14
(3,491 Views)

It should be simply a value. The HANDLE is a pointer datatype but that is taken care of by configuring it as pointer sized integer. You only would need to pass it as pointer to value if the function prototype would look like this:

 

int function_name9..., HANDLE *handle, ...)

The * in front of the variable name indicates that the parameter is passed as a reference type and that corresponds to the pointer to value configuration in a Call Library Node.

Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 14
(3,488 Views)

Great, thanks again. That was going to be my next question - how to determine which to use based on the handle definition in the header file. 

 

If changing the handle setup doesn't improve reliability, do you (or others) have any thoughts on moving to use the VISA USB functions? Or even swapping the dll with the winusb API? I've never used VISA for USB, so I'm not sure how robust/reliabile it is.

0 Kudos
Message 9 of 14
(3,483 Views)

I'm not sure why changing the handle to be a pointer sized integer from an 32-bit integer would improve reliability if you use this in 32-bit LabVIEW. It is simply a change that should be done to avoid problems when you later happen to use this library in 64-bit LabVIEW for whatever reason. This may sound to much of bothering, but there will be a time when LabVIEW is only distributed as 64-bit anymore, as is already the case for Linux and Mac if I'm not mistaken.

 

The use of VISA USB is most likely not an easy option. You would need to use VISA USB Raw communication for that and that requires a complete and full documentation of the actual low level USB protocol used. I'm not sure Microchip is willing or prepared to share such a document with you or anyone else for that matter.

 

Well it seems they provide the code for the MPUSBAPI.dll here but extracting the actual protocol documentation from this is going to be quite a bit of work. And then you need to implement it on top of VISA USB Raw which is a tedious process.

Rolf Kalbermatter
My Blog
0 Kudos
Message 10 of 14
(3,477 Views)