From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

NI-Device crashes with serial polls

Using Windows NT, NI-Device crashes unpredictably. Works fine with many reads and writes but eventually crashes if serial polls are included.
0 Kudos
Message 1 of 7
(3,832 Views)
What version of NI-Device are you using? Can you provide a sequence of events that can duplicate the crash? Does the crash culminate in a BSOD? If so, what information does the BSOD provide?
Message 2 of 7
(3,832 Views)
Thanks for your interest. I'm using NI-Device 1.1. I've made a loop that uses NI-488 commands with a lot of ibonls, ibdevs ibwrts, ibrds and a couple of ibrsps. If I take the ibrsps out, it runs indefinitely. With the ibrsps, it causes the application using NI-Device to crash. A message box appears saying, "The instruction at 0xC referenced to memory at 0xC. The memory could not be "read"". The crash happens randomly, after only a few loops or a few hundred loops. I have found that putting in a Sleep(30) before an ibrsp() call seems to fix it. At least I can do 10000 loops without a problem. I would prefer to fix it on the NI-Device machine. I am doubtful that putting in a delay in StatusByteRequestedCallback () will help. Any suggestions/insights appre
ciated.
0 Kudos
Message 3 of 7
(3,832 Views)
I am currently running a test similar to your test. It does a lot of writes, reads, serial polls, and takes a session on and off. I am running it against the SimpleDevice that comes with NI-Device 1.1 running on Windows NT4. So far, I have been unable to reproduce any crash (I have run it for about 30 minutes).

There are two possibilities.
1) The crash is actually in your application. When you do serial polls, you may have a race condition that causes this.
2) I have not run it long enough or my test does things differently.

To attempt to narrow down problem 1, you can try to run your tests against the Example that is provided with NI-Device. If you have a debug version of your application, that could help as well. Also, if you have a
good debugger, such as SoftICE, you can get a stack trace once the crash occurs to see if you can isolate which component is causing the crash.

To narrow down problem 2, I will continue testing to see if continuing to run the test causes the crash to occur. I will also create a new test that runs the commands a bit tighter in a loop to more simulate your timing conditions.

One other thing to note. We now recommend that you no longer use the StatusByteRequestedCallback and instead use the UpdateStatusByte method. This is because Serial Polls have unique timing characteristics and delaying too long in the callback can cause the timing to be missed and bus errors to be received. This is actually more apparent on other buses, but is applicable to GPIB as well. In some cases (such as creating a translator application that needs to propegate the status request across the bus) the callback is necessary. However, if it is not necessary, we recommend using the other method. Does this ma
ke sense? I can clarify it more if necessary.
0 Kudos
Message 4 of 7
(3,832 Views)
Thanks again for your reply. One difference in my application is that I modified SimpleDevice to be a dll. That requires some extra changes to SimpleDevice and an executable to run it and may explain the difference in behavior. At any rate, by simply taking out the StatusByteRequestedCallback(), it looks promising (further testing needed) that the crashes no longer occur. HOORAY! Now what I don't understand is how to send my variable m_StatusByte to the Controller. My feeble guess is that when the m_StatusByte should change, I call UpdateStatusByte to set m_StatusByte (but why do I need the function to set it?), then call RequestService(), which I haven't overridden. Then whenever Controller does a serial poll, it will get the updated m_Stat
usByte (but how? how does my class member m_StatusByte get over to NI-Device to send to the Controller without a callback function?)

Another question involves the fact that I wanted to set m_StatusByte back to 0 after a serial poll. So I put the following code at the end of StatusByteRequestedCallback():

if (m_StatusByte)
{
BYTE StatusByte = m_StatusByte;
m_StatusByte = 0;
return StatusByte;
}
return m_StatusByte;
}

Can I still do that? Without StatusByteRequestedCallback(), how will I know when a serial poll has occurred, and thus know when to set m_StatusByte back to zero?


Another minor question is what is "eStatusMessage"?
0 Kudos
Message 5 of 7
(3,832 Views)
Let me answer some of your questions (I hope I get them all!).

1) You are correct. When your status byte changes, you should call UpdateStatusByte to copy your status byte into the driver. NI-Device maintains a copy of the status byte updated this way. When NI-Device gets serial polled, it returns the stored copy instead of requesting it from the user.

2) When you want to request service, you would call RequestService after you update the status byte. NI-Device will propegate the SRQ across the bus to the controller and will automatically OR in bit 6 to the service request response. RequestService is not an overridable method.

2) In regards to setting it to zero after a serial poll. This is not common behavior for a device. Typically the serial poll returns the current status of the device. If the device is requesting service, bit 6 is ORed into the status byte (automatically by NI-Device). Subsequent status byte requests should still return the status byte of the device, but typically this would be without bit 6. Just because you are serial polled does not mean that the status of your device has changed. When it does change, the status byte will be updated again. If this new change causes the device to request service, the cycle continues again.

4) Without the STBCallback, you do no know when a serial poll has occurred.

5) Are you trying to create a 488.2 compliant instrument? If so, you may want to consider upgrading to a newer version of NI-Device. NI-Device 1.5 is just being released. Newer versions of NI-Device have a slightly different API (very similar, but some minor usability tweaks) and provide full support for the IEEE 488.2 Message Exchange Protocol, which is a state machine that helps make a more reliable instrument. However, it also limits the instrument in what it is capable of doing. IEEE 488.2 does not allow you to zero out your status byte after being serial polled and doesn't allow the device to generate a response message unless the host sends a valid query first. I am not sure how familiar you are with IEEE 488.2.

6) I ran my test all day yesterday and never ran into any problems. I modified it to add a tight loop and when I get back to the office, I can probably send you the executable to see if it reproduces the crash for you.

7) What is eStatusMessage? eStatusMessage is the variable that NI-Device uses to pass the status of an API call. After calling RequestService, you can look at the eStatusMessage variable to determine if the call was successful or if it failed. It is actually an enumerated type that defines each particular failure. You create a variable of this type to store the status for each API call. Does this make sense?

Thanks.
0 Kudos
Message 6 of 7
(3,832 Views)
Thanks very much for your quick and thorough replies. I tested my software with UpdateStatusByte() instead of STBCallback() over the weekend with a million loops of two serial polls each with no problems. No need to send me an executable. Actually, I ran SimpleDevice myself without problems. Perhaps at least part the reason I had problems was due to the fact that I have my NI-Device software in a dll, not executable. Thanks again for your speedy answers, I have no questions at the moment.
0 Kudos
Message 7 of 7
(3,832 Views)