Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Getting a System.ExecutionEngineException from ni4882.dll

I'm reading ASCII trace data from an instrument, and every so often I get an unrecoverable System.ExecutionEngineException. I'm pretty puzzled by what's going on, and would appreciate any advice any of you could offer. Here are the details:

I'm using an NI GPIB-USB-B interface. My software is written in C#, and uses the .NET class libraries that ship with the interface. The computer's OS is Windows XP professional, SP2. I'm pretty sure I have the most current versions of the drivers, etc.

I'm trying to read a large (~10k bytes) trace from an HP 8720A network analyzer. I use the .NET NationalInstruments.NI4882.Device.ReadString() method to read the data. I notice that the larger the trace is, the more frequently the error occurs. With 1kbyte transfers, I never get the error. With 5 kbyte transfers, the errors occur occasionally, and with 10 kbyte transfers they are frequent. As far as I can tell this type of exception is unrecoverable and uncatchable, so the only alternative is to abort the program and try again.

I've tried setting the Device.DefaultBufferSize and Board.DefaultBufferSize properties to be sufficiently large, but it doesn't seem to help. I've also tried using the Device.ReadString(int NumBytes) method to read a fixed number of bytes in, to no avail.

If anyone can offer some guidance to me, I'd appreciate it, as I seem to have run out of tricks. It looks to me like there's some kind of bug in the ni4882 driver, and I fear there may be no workaround.

Thanks for your time,
Terry Noe
terry_noe@beehive-electronics.com
0 Kudos
Message 1 of 7
(4,625 Views)
Can you post the code that is causing the exception? Also, can you provide a stack trace from when the exception occurs? What is the format of the data you're acquiring - you said it's ASCII trace data; does that mean it's comma-delimited numbers, or some other format?
0 Kudos
Message 2 of 7
(4,612 Views)
Thanks for your interest. In reply to your questions:

Here's a condensed version of the code:

// First, I open the GPIB interface:

public NationalInstruments.NI4882.Board GpibBoard = new Board();

//Then, I open the instrument:

public virtual void Open()
{
if (lclAddress != "")
{
try
{
if (device != null)
{
device.Dispose();
}
device =new Device(Convert.ToInt32(GpibIntfcNum),Convert.ToByte(lclAddress));
device.Clear();
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show("Exception opening device: "+ex.Message);
}
}
}

//Here is the code that causes the instrument to return the trace:

string ReturnString="";
device.Write("SING;\n"); //Instructs the network analyzer to take a sweep
device.Write("FORM4;\n"); //Sets the trace format to ascii
NationalInstruments.NI4882.TimeoutValue ReadTO = NationalInstruments.NI4882.TimeoutValue.T30s; //Set the timeout to 30s, just in case
device.IOTimeout=ReadTO;
device.Write("OUTPFORM;\n"); //Instructs the network analyzer to return the trace data
ReturnString=device.GPIBGet(); //Trying to read back the ascii trace - this is where the error occurs.


Here's what the call stack looks like:

Call stack:
[]
VnaRead.exe!GPIBControlInstrument.GPIBGet() Line 149 + 0xe bytes
VnaRead.exe!VNA_8720_NS.VnaDriver.GetSweepData(int NumperOfPoints=201) Line 274 + 0x8 bytes
VnaRead.exe!VnaReadNS.SimpleVnaTest.Run() Line 33 + 0x13 bytes
VnaRead.exe!VnaReadNS.VnaRead.cmdTest_Click(System.Object sender = {Text="Simple Test"}, System.EventArgs e = {System.EventArgs}) Line 500
[]
VnaRead.exe!VnaReadNS.VnaRead.Main() Line 367

With the exception of the 'non-user code', there's nothing here to me that looks mysterious or unexpected.


Finally, regarding the ascii data format. The trace is a series of complex number pairs. The real and imaginary components are separated by a comma, and the different trace points are delimited by a \n. So, for example,

1.234E-005, 6.789E-001\n2.345E-006, 7.890E-001\n et cetera.

There's one more interesting point I should mention. I have also tried doing asynchronous read/writes. Thre results here are interesting. The previously mentioned ExecutionEngineException doesn't occur, but instead I'll get a full trace back. The problem is, the end of the string is all a bunch of \0's. The length of the corrupt section varies, but can be hundreds or thousands of bytes. My programming expertise is nothing to brag about, but this seems like the type of thing that could be caused by a bad pointer in the dll.

Thanks for your interest in my problem. Feel free to ask further questions if it helps; and I can certainly provide a fuller code sample if it would be helpful.

Terry Noe
terry_noe@beehive-electronics.com
0 Kudos
Message 3 of 7
(4,603 Views)
Whoops, one thing I left out of my code:

Before I try to read the string, I set the DefaultBufferSize property to the expected length of the returned string:

device.DefaultBufferSize=StringSize;

Unfortunately, it doesn't seem to help.

Terry Noe
0 Kudos
Message 4 of 7
(4,603 Views)
Hello,

You mention in your first post that you use the ReadString() method, but I don't see that in the code you posted. In general, the data that comes back to you in nicely formatted... are all data points returned using the same number of bytes (that is, are the same number of characters used to represent returned data)? If so, you should be able to read more frequently. More specifically, you could read your data in chunks, say, some integer number of data points. If not, you can simply read in chunks, and parse each chunk for \n... to separate your data points... just keep any trailing part of a chunk and concatenate the next chunk onto it to preserve the data points which are "cut" by the "chunk reading." Are either of these viable workarounds in the event a more fundamental solution exists?

Repost and if necessary we can play with more ideas.

Thank you,

JLS
Best,
JLS
Sixclear
Message 5 of 7
(4,587 Views)
Thank you for the excellent suggestion, JLS! I tried your suggestion (that I read out the large string in smaller chunks), and it seems to work great. I read out a 10050 byte string in 500 byte chunks. I ran the test 500 times with no errors.

You are, of course, correct to point out that the code I posted does not show a call to the ReadString() method. The line:

ReturnString=device.GPIBGet(); //Trying to read back the ascii trace - this is where the error occurs.

is eventually a call to device.ReadString(), I forgot to rewrite that line to be more obvious.

FYI, here's the new code that seems to work:

string ReturnString="";
int CharsPerPoint=50; //The number of bytes transmitted per data point
int TotalStringSize = NumberOfPoints*CharsPerPoint; //Calculates the total number of bytes expected
int MaxChunkSize=500; //This is the maximum size of the substrings we read at one time
int ChunkSize;
device.Write("OUTPFORM;\n"); //Instructs the instrument to return an ascii-formatted trace
while (ReturnString.Length < TotalStringSize)
{
ChunkSize=Math.Min(MaxChunkSize,(TotalStringSize-ReturnString.Length)); //If the end of the trace is less than 500 bytes, just read the correct amount
ReturnString+=device.ReadString(ChunkSize); //Since \n's are inside the string, we don't want to delete them
}

Thank you very much for your suggestion. Like a lot of great ideas, it seems obvious in hindsight, but it never would have occurred to me. Thanks also to Glen Burnside for his post.

Terry Noe
terry_noe@beehive-electronics.com
0 Kudos
Message 6 of 7
(4,580 Views)
Great! Glad it was an acceptable solution for the application!

Feel free to repost if you encounter anything else 🙂

Best Regards,

JLS
Best,
JLS
Sixclear
0 Kudos
Message 7 of 7
(4,569 Views)