rs232 synchronization issues at 115200

G

Guest

Hi,

I developed two applications to test a flush() method in my application, but I am having some problems when running it at high baud rates (115200)

I connected two computers using a cross-talk cable and wanted to test if all data sent from application 1 was correctly received by application 2 (test the flush method).

The first application is the receiver - basically it opens the serial port and loops infinitely. Inside the loop, it reads from the port and sleeps for 1 seconds (simulating a very slow connection). It also counts the number of bytes received so that I can compare if all data sent was received

The second application is the transmitter - It opens the serial port for a SYNCHRONOUS connection, and uses the WriteFile method to write a certain small buffer (26 bytes) N times. It consists of several loops, where right after writing the data it calls my flush() method which checks if the TX buffer is empty (checks if all data sent were received).
If TX buffer has any bytes on it, them the application sleeps for some while, waiting till all data is transmitted. Otherwise, it goes to the next iteration of the loop, to write more data

The program runs fine if I do not open the serial port at 115200. When running it at this specific bit rate, most of the data sent is lost (the transmitter sends everything, but not all data is received by the received application)

The TX buffer is always empty, which - according to MS documentation - is correct because I am using a synchronous connection. However, I don't understand how couldn't the data be sent! Why am I loosing data? Shouldn't it be supposed to be synchronized?? It there anything else I should do after writing the data (after calling WriteFile) to guarantee that the data was received

Both machines are running Windows 2000
Software was developed using Visual C++ 6.0 - pure win32 application (no .NET use - yet)

Any help would be greatly appreciated

Regard

Pete
 
W

Will Dean

Peter Hans said:
The second application is the transmitter - It opens the serial port for a
SYNCHRONOUS connection,

I don't know what you mean here, but you don't mean SYNCHRONOUS. Are you
talking about flow control?
The program runs fine if I do not open the serial port at 115200. When
running it at this specific bit rate, most of the data sent is lost (the
transmitter sends everything, but not all data is received by the received
application).

You need to call ClearCommError to find out what kind of error you're
getting. I strongly suspect you'll be seeing overflows, because you have no
flow control.
The TX buffer is always empty, which - according to MS documentation - is
correct because I am using a synchronous connection. However, I don't
understand how couldn't the data be sent! Why am I loosing data? Shouldn't
it be supposed to be synchronized?? It there anything else I should do after
writing the data (after calling WriteFile) to guarantee that the data was
received?

You need to make sure you've called the following things on the serial port
before you start anything else, and understood what they all mean:
SetupComm, Get/SetCommState, SetCommTimeouts.

If you've missed-out one of these, then you're using completely unknown
settings, and you'll struggle to get anything working.

It's not at all easy to get serial comms right, so you need to be careful at
every stage.


Will
 
G

Guest

Thanks for answering

I tested the overflow condition you stated and you are correct. The Transmitter application is causing an overflow! It is writting more data than the Receiver's application can consume. Is there anyway to solve this without using flow control mechanisms? The kind of devices that my application will be using may not support any FLOW control

I was trying to use the COMSTAT.CbOutQue structure, returned by the method ClearCommError method to check the number of byte that are still on the transmitter's buffer, but it always returns 0 for serial devices. The idea was to force the Transmitter application to sleep while this value was greater than zero.

Regarding the SYNCHRONOUS, I was refering to the way the CreateFile is being called in my application to open the serial port - I am no using the OVERLAPPED flag.

regard

Peter
 
C

Carl Daniel [VC++ MVP]

Peter said:
Thanks for answering!

I tested the overflow condition you stated and you are correct. The
Transmitter application is causing an overflow! It is writting more
data than the Receiver's application can consume. Is there anyway to
solve this without using flow control mechanisms? The kind of devices
that my application will be using may not support any FLOW control.

I can't give you a worked-example, since I don't have one lying about, but
in order to receive without dropping characters, you need to use overlapped
I/O and asynchronous reads.

The general pattern is to start two (or more) async read requests, and each
time a request completes, process the received data and then start another
read request. You need to have enough read requests queued to cover
whatever processing time your applicaion needs (you may need to do some
experimentation varying buffer sizes and number of outstanding reads).
Using overlapped I/O, your program can easily receive data at rates of
megabytes per second without dropping any data on a modern PC.

-cd
 
W

Will Dean

Carl Daniel said:
I can't give you a worked-example, since I don't have one lying about, but
in order to receive without dropping characters, you need to use overlapped
I/O and asynchronous reads.

I'm not 100% convinced that going overlapped is necessarily *essential*. If
you set a big receive buffer with SetupComm, then be appropriate behaviour
with ReadFile and SetCommTimeouts, you should be able to keep up with
ordinary serial port rates.
Using overlapped I/O, your program can easily receive data at rates of
megabytes per second without dropping any data on a modern PC.

This multi-read/buffering scheme is definitely the ultimate, but it's not
trivial to implement, and might be more than the OP needs or wants at this
stage. I'd reckon he should play around with RX buffer sizes a bit first.

Will
 
C

Carl Daniel [VC++ MVP]

Will said:
"Carl Daniel [VC++ MVP]"
I can't give you a worked-example, since I don't have one lying
about, but in order to receive without dropping characters, you need
to use overlapped I/O and asynchronous reads.

I'm not 100% convinced that going overlapped is necessarily
*essential*. If you set a big receive buffer with SetupComm, then be
appropriate behaviour with ReadFile and SetCommTimeouts, you should
be able to keep up with ordinary serial port rates.
Using overlapped I/O, your program can easily receive data at rates
of megabytes per second without dropping any data on a modern PC.

This multi-read/buffering scheme is definitely the ultimate, but it's
not trivial to implement, and might be more than the OP needs or
wants at this stage. I'd reckon he should play around with RX buffer
sizes a bit first.

True in both regards. Multi-buffered overlapped I/O is tricky at best - but
there's no doubt that any PC runing Windows (let alone a modern one) can
handle 115200 baud with overlapped reads.

-cd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top