Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

ENET-485/4 with GetOverlappedResult occasionally indicates zero bytes sent

We are using an ENET-485/4 device in a Windows 2000 system.  Our application uses the Win32 system calls to access the COM ports.  We open the port using the CreateFile function and specify the FILE_FLAG_OVERLAPPED flag.  We then have two separate tasks:  one for receive and one for transmit.  The receive task calls the ReadFile function and specifies an OVERLAPPED structure.  It then calls and waits on the GetOverlappedResult function.  Likewise, the transmit task calls the WriteFile function and specifies an OVERLAPPED structure.  It then calls and waits on the GetOverlappedResult function.
 
Occasionally, in the transmit task, the GetOverlappedResult function returns a successful completion status but indicates that zero bytes were sent.
 
This same software is used to access COM ports on a 3rd-party PCI RS-485 card and we don’t see this behavior.
 
Has anyone seen this?
I've attached a file with some code snippets to illustrate the system calls.
0 Kudos
Message 1 of 7
(5,788 Views)
 

Hi CME12345,

What version of the NI-Serial driver are you using in your setup? This may be something that was corrected in a later version of the driver.

Current Serial Drivers Page

Regards,
Matt S.

 

LabVIEW Integration Engineer with experience in LabVIEW Real-Time, LabVIEW FPGA, DAQ, Machine Vision, as well as C/C++. CLAD, working on CLD and CLA.
0 Kudos
Message 2 of 7
(5,771 Views)
We are using NI-Serial version 3.0.
0 Kudos
Message 3 of 7
(5,769 Views)
What is the value of Num_Written after the write command, before you run GetOverlappedResult?  I am curious to know if the number written in the write command is zero as well, or if they are mismatched.

Jason S.
Applications Engineer
National Instruments
0 Kudos
Message 4 of 7
(5,756 Views)
Num_Written is zero after the WriteFile command.  This seems to make sense to me because with overlapped I/O, the WriteFile command returns immediately, before the transfer is complete.
0 Kudos
Message 5 of 7
(5,731 Views)
As Jason mentioned the problem with your program is that if the WriteFile is able to complete the write in the context of the write call the WriteFile will return the number of bytes and the I/O will not be overlapped. This is very possible when you are using the ENET because it has 128 byte FIFOs instead of 16 byte FIFOs found on most generic serial ports. If the driver is able to fit the entire write into the FIFO on the first try the WriteFile will complete.

Currently, your program is a little overly simplified. From the MSDN documentation "If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile may return before the write operation has been completed. In this case, WriteFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This allows the calling process to continue processing while the write operation is being completed. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the write operation. The caller must adjust the position of the file pointer upon completion."

You need to be checking if the WriteFile returns FALSE before calling GetOverlappedResults. If the WriteFile returns TRUE the write was able to complete in the contect of the WriteFile.

Further documentation on this can be found on the MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/writefile.asp)

-Josh
0 Kudos
Message 6 of 7
(5,716 Views)

I have discovered what is causing my problem.  The problem is caused by the values I am using in the COMMTIMEOUTS structure (see the original attached file with the code snippets).

 

Here is the MSDN reference regarding COMMTIMEOUTS:  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcecoreos5/html/wce50lrfcommtimeout...

 

The bottom line is that my code is allowing 10 msec per byte for the transmit to complete.  This code has worked for years on a 3rd-party PCI RS-485 card.  I believe that this timeout value is occasionally being exceeded with the ENET-485, perhaps due to network latencies or some other communication delay between the computer and the ENET-485.  It is interesting (and frustrating) that in this case, the call to GetOverlappedResult appears to complete with no error (i.e., the return value is nonzero).

 

If I make the following change, which sets the timeout to 5 seconds, I no longer have this problem:

 

   Comm_Timeouts.WriteTotalTimeoutMultiplier = 0;

   Comm_Timeouts.WriteTotalTimeoutConstant   = 5000;

 

0 Kudos
Message 7 of 7
(5,624 Views)