LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW coding using wnaspi32.dll

Hi to all, here I need you guys help in LV coding with wnaspi32.dll for I have no experience in doing that at all!

I will appreciate if any of you can tell me what the equivalent in lv code for

1)
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
WORD SRB_Rsvd1; // Reserved for Alignment
DWORD SRB_BufLen; // Data Allocation Length
BYTE *SRB_BufPointer; // Data Buffer Point
BYTE SRB_SenseLen; // Sense Allocation Length
BYTE SRB_CDBLen; // CDB Length
BYTE SRB_HaStat; // Host Adapter Status
BYTE SRB_TargStat; // Target Status
void (*SRB_PostProc)(); // Post routine
void *SRB_Rsvd2; // Reserved
BYTE SRB_Rsvd3[16]; // Reserved for expansion
BYTE CDBByte[16]; // SCSI CDB
BYTE SenseArea[SENSE_LEN+2]; // Request Sense buffer
}

2.) In the following example, how do I do the (a) and (b) correctly?

This example sends a SCSI Inquiry command to host adapter #0, target #0, LUN
#0.

SRB_ExecSCSICmd MySRB;
DWORD ASPIStatus;
(a) char InquiryBuffer[32];
.
.
.
MySRB.SRB_Header = SC_EXEC_SCSI_CMD;
MySRB.SRB_HaId = 0;
MySRB.SRB_Flags = SRB_DIR_IN | SRB_POSTING;
MySRB.SRB_Hdr_Rsvd = 0;
MySRB.SRB_Target = 0;
MySRB.SRB_Lun = 0;
MySRB.SRB_BufLen = 32;
MySRB.SRB_SenseLen = SENSE_LEN;
(b) MySRB.SRB_BufPointer = InquiryBuffer;
MySRB.SRB_CDBLen = 6;
MySRB.RB_PostProc = PostProcedure;
MySRB.CDBByte[0] = SCSI_INQUIRY;
MySRB.CDBByte[1] = 0;
MySRB.CDBByte[2] = 0;
MySRB.CDBByte[3] = 0;
MySRB.CDBByte[4] = 32;
MySRB.CDBByte[5] = 0;

I am really struggling in getting it right for the *SRB_BufPointer (data buffer pointer) to work so as the aspi32.dll function will returns data to the pointer's buffer. But

q: How do get this buffer pointer correctly and how to read the buffer data after?

Hope that I am giving enough information on my problem. And, I will really aprreciate if anyone of you out there can help me on this. really.

Hear from ya.
Cheers and warmest regards
ian
ian@ianfung.net
Ian F
Since LabVIEW 5.1... 7.1.1... 2009, 2010, 2014
依恩与LabVIEW
LVVILIB.blogspot.com
0 Kudos
Message 1 of 9
(4,761 Views)
Dear Ian,

1:
a)
The problem with this structure is that it holds a pointer to a callback function, parameter "void (*SRB_PostProc)(); // Post routine". This is not supported under LV. If you can guarantee that this function will never be called by setting of some of the other parameters or will not be nesseccarilly be called to complete succeefully you can fill this with a U32 containing 0. Maybe this will be the only way by design that this function is not to call.
b)
The next one you cannot do is the "BYTE *SRB_BufPointer; // Data Buffer Point
" parameter. You cannot tell LV that the element in the Cluster should only contain a pointer to the data and not the data itself.
c)
LV does not store array data directly in a clust
er. So the last three parameters cannot be represented as data in a cluster. Maybe this will be corrected by the "Adopt to type" Property in the "Configure DLL call".

2:
a)
This is done by using "Initialize Array" with a U8 and 32 elements set to 0. This will create a buffer.
b)
This is done by bundle by name.

But for problem 1b 2b will not do the right thing. It will insert a handle to the array and not a pointer to the array.

The only chance you have is building a wrapper DLL or CIN to avoid those pointer operations.

Waldemar
Waldemar

Using 7.1.1, 8.5.1, 8.6.1, 2009 on XP and RT
Don't forget to give Kudos to good answers and/or questions
Message 2 of 9
(4,761 Views)
Waldemar, I appreciate your inputs.
This is the first time I encounted the real limitation of LabVIEW!

Perhaps, NI should spare some time to look into this matter as most of us do not just simply deal with LV but also third party drivers etc.

Still, if anyone out there has got any built wrapper DLLs or CINs for the above, I would very much appreciate that you can post them here or email to me.

regards
ian
Ian F
Since LabVIEW 5.1... 7.1.1... 2009, 2010, 2014
依恩与LabVIEW
LVVILIB.blogspot.com
0 Kudos
Message 3 of 9
(4,761 Views)
> Perhaps, NI should spare some time to look into this matter as most of
> us do not just simply deal with LV but also third party drivers etc.
>
> Still, if anyone out there has got any built wrapper DLLs or CINs for
> the above, I would very much appreciate that you can post them here or
> email to me.
>

The limitation here is that LV VIs don't by default have C entrypoints.
If you have the professional version of LV, you can build a DLL with C
entrypoints, and possibly with types that match the signature of the
callback. Without the signature info, I can't tell you. But you also
need a way of passing a function pointer. You can do this with a small
wrapper DLL, or you might be able to directly call the Win32
LoadProcAddress
, giving it the DLL and function name and passing the
function pointer around as an int32.

Greg McKaskle
0 Kudos
Message 4 of 9
(4,761 Views)
hi Greg,

Noted your input. Will give it a try 🙂
Ian F
Since LabVIEW 5.1... 7.1.1... 2009, 2010, 2014
依恩与LabVIEW
LVVILIB.blogspot.com
0 Kudos
Message 5 of 9
(4,761 Views)
Dear Greg,

this would solve the problem 1a.

For 1b I can define a U32 for SRB_BufPointer. I can create the buffer with "Initialze Array" but I don't know how to assign the address of the array to a U32. I made a look into the "LV Data Storage" but not into the "External Code" document so my knowledge is limited. On this basis I thougth it is not possible with LV to create a Cluster with the same memory layout as the typedef struct and suggested to use a wrapper DLL.

Waldemar
Waldemar

Using 7.1.1, 8.5.1, 8.6.1, 2009 on XP and RT
Don't forget to give Kudos to good answers and/or questions
0 Kudos
Message 6 of 9
(4,761 Views)
Dear all,

A wrapper DLL certainly do the job!
And, I will try out other possible solutions mentioned by you guys as and when is possible.

Thanks for your invaluable inputs/ suggestions, and hope these will also benefits many others.

Cheers!
ian
Ian F
Since LabVIEW 5.1... 7.1.1... 2009, 2010, 2014
依恩与LabVIEW
LVVILIB.blogspot.com
0 Kudos
Message 7 of 9
(4,761 Views)
Well, I don't think NI should spend much time on this. The configuration screen necessary to configure all those options really would be a mess to deal with and you would still need to know all the detail knowledge about C data types, how they are passed between functions, particular byte boundary alignement etc.

Without this knowledge present you still couldn't use these options and once you have the knowledge, writing a simple wrapper DLL which goes between LabVIEW and your complicated data structure and possibly callback API is actually much simpler than trying to configure and possible wire your API interface in LabVIEW.

Of course knowing the layout of the LabVIEW data structures you can basically use a trick to get the pointer to a LabVIEW string into a data structure to be passed to a DLL but it is still far from simple. The callback pointer however can't be tricked from a LabVIEW diagram (at least not without so much magic that writing a DLL is actually hundred times faster than trying to get this to work in LabVIEW).

You need to know that LabVIEW byte arrays are basically a pointer to a pointer to a buffer with an additional i32 at the beginning indicating the size. So by allocating a LabVIEW array you can then place a Call Library Node on the diagram with following configuration:

library: LabVIEW
function name: MoveBlock
return value: void
first parameter: LabVIEW array handle of uInt8
second parameter: uInt32 pointer to value
third parameter: int32 value

Then wire the array to the first parameter, a 0 constant to the second and a 4 constant to the third. The resulting value from the second parameter is the pointer to the effective LabVIEW array buffer and adding 4 to this value will be the pointer to the begin of the actual array.

Make sure the array wire stays valid until the Call Library Node returns (by wiring it to a structure boundary which depends on some output of the Call Library Node and not branching the wire to anyplace else until that point) and resize the array after the Call Library Node returns, by the actual size returned somewhere from the Call Library Node. Make sure the intial array is as large as required by the API function or as you have indicated in one of the parameters to the API function as otherwise the function will crash.

Remains filling in the structure which will be a bit of a pain also, but I told you that writing a wrapper DLL is almost always faster than trying to do such things in LabVIEW.

Rolf Kalbermatter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 8 of 9
(4,761 Views)
There is one problem with above. The first MoveBlock call only returns the master pointer of the handle and you need to do a second dereferencing after that to get the actual array pointer.

Create a second Call Library Node similar to the first:

library: LabVIEW
function name: MoveBlock
return value: void
first parameter: uInt32 value
second parameter: uInt32 pointer to value
third parameter: int32 value

Wire the second parameter returned by the first MoveBlock call to the first parameter of this MoveBlock. Wire a 0 constant to the second parameter and again 4 to the third. Add 4 to the value returned from the second parameter of this Call Library Node and you now have the actual pointer to the LabVIEW array data.

Rolf Kalber
matter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 9 of 9
(4,761 Views)