Serial Driver not feeding UART Timely?

Hi,

I am attempting to communicate with some external hardware via RS-232. The
problem is that timeouts are occurring because the data that is being sent
from the PC is unacceptable time gaps (13-24 milliseconds; usually a pattern
two characters with a 6-7 ms delta, then one with a 13-24 ms delta, then two
more 6-7 ms gaps, etc… It’s the 13-24 ms time gap between characters that
is causing the problem). I contacted the author of the (popular) library I
am using to send the data over the serial port, however he is stating that
these gaps are not his library’s fault, but rather the Windows serial port
driver’s fault in not feeding the UART consistently and as timely as the
receiving hardware requires. My investigations into the matter seem to be
conclusive; however I am interested in second opinions.

Assuming the driver is at fault, what is going to be the best route to fix
the problem? For example, can a filter driver solve this problem? And if so,
what specifically should I begin to read up on?

Thank you,
Steve

Fix your hardware.

RS-232 is async interface which provides no timing guarantees - except
between bits in a byte :slight_smile:

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “Stephen”
To: “Windows System Software Devs Interest List”
Sent: Thursday, December 23, 2004 7:27 PM
Subject: [ntdev] Serial Driver not feeding UART Timely?

> Hi,
>
> I am attempting to communicate with some external hardware via RS-232. The
> problem is that timeouts are occurring because the data that is being sent
> from the PC is unacceptable time gaps (13-24 milliseconds; usually a pattern
> two characters with a 6-7 ms delta, then one with a 13-24 ms delta, then two
> more 6-7 ms gaps, etc… It’s the 13-24 ms time gap between characters that
> is causing the problem). I contacted the author of the (popular) library I
> am using to send the data over the serial port, however he is stating that
> these gaps are not his library’s fault, but rather the Windows serial port
> driver’s fault in not feeding the UART consistently and as timely as the
> receiving hardware requires. My investigations into the matter seem to be
> conclusive; however I am interested in second opinions.
>
> Assuming the driver is at fault, what is going to be the best route to fix
> the problem? For example, can a filter driver solve this problem? And if so,
> what specifically should I begin to read up on?
>
> Thank you,
> Steve
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Try increasing your task or thread priority on the application sending data and see what that does.

Alternately (or as well) if possible don’t send individual characters - format the entire string and send it as a string.

Loren

-----Original Message-----
From: Stephen
Sent: Dec 23, 2004 8:27 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Serial Driver not feeding UART Timely?

Hi,

I am attempting to communicate with some external hardware via RS-232. The
problem is that timeouts are occurring because the data that is being sent
from the PC is unacceptable time gaps (13-24 milliseconds; usually a pattern
two characters with a 6-7 ms delta, then one with a 13-24 ms delta, then two
more 6-7 ms gaps, etc… It’s the 13-24 ms time gap between characters that
is causing the problem). I contacted the author of the (popular) library I
am using to send the data over the serial port, however he is stating that
these gaps are not his library’s fault, but rather the Windows serial port
driver’s fault in not feeding the UART consistently and as timely as the
receiving hardware requires. My investigations into the matter seem to be
conclusive; however I am interested in second opinions.

Assuming the driver is at fault, what is going to be the best route to fix
the problem? For example, can a filter driver solve this problem? And if so,
what specifically should I begin to read up on?

Thank you,
Steve


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@earthlink.net
To unsubscribe send a blank email to xxxxx@lists.osr.com

Unfortunately if he is speaking to something that uses the ^&*)& “Sony 9-pin protocol” he is stuck with a 9ms timeout between characters that will automatically (and almost always incorrectly) terminate a transmission.

Unless of course the implementers of the device were smart and ignored the 9ms requirement in the protocol spec. Doesn’t sound like that is the case here though.

In any case I deal with idiot devices like that very commonly, and almost never have problems, unless they also specify idiotically tight turnaround requirements too. The trick is to keep the thread priority up, use async IO, set the timeouts correctly, and send and receive strings rather than individual characters whenever possible.

Loren

-----Original Message-----
From: “Maxim S. Shatskih”
Sent: Dec 23, 2004 5:54 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Serial Driver not feeding UART Timely?

Fix your hardware.

RS-232 is async interface which provides no timing guarantees - except
between bits in a byte :slight_smile:

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “Stephen”
To: “Windows System Software Devs Interest List”
Sent: Thursday, December 23, 2004 7:27 PM
Subject: [ntdev] Serial Driver not feeding UART Timely?

> Hi,
>
> I am attempting to communicate with some external hardware via RS-232. The
> problem is that timeouts are occurring because the data that is being sent
> from the PC is unacceptable time gaps (13-24 milliseconds; usually a pattern
> two characters with a 6-7 ms delta, then one with a 13-24 ms delta, then two
> more 6-7 ms gaps, etc… It’s the 13-24 ms time gap between characters that
> is causing the problem). I contacted the author of the (popular) library I
> am using to send the data over the serial port, however he is stating that
> these gaps are not his library’s fault, but rather the Windows serial port
> driver’s fault in not feeding the UART consistently and as timely as the
> receiving hardware requires. My investigations into the matter seem to be
> conclusive; however I am interested in second opinions.
>
> Assuming the driver is at fault, what is going to be the best route to fix
> the problem? For example, can a filter driver solve this problem? And if so,
> what specifically should I begin to read up on?
>
> Thank you,
> Steve
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@earthlink.net
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks for that Loren. The hardware in question was designed to speak with
another piece of hardware, which is what I need to now emulate through a PC
on WinXP (it was first written for DOS). Changing the hardware is not an
option. Anyway, I did manage to get some better response time by fiddling
with the thread priorities; I actually had to bring one BelowNormal and
another AboveNormal, as High was too High…

Anyway, I realized that in development I was using a Keyspan Serial to USB
Link when I got the software working. Response times were adequate: 13ms
between last byte received and first byte sent out. So I tried directly
connecting to the serial port (which was behind the computer and thus why I
elected to use USB in first place!) and to my surprise the communications
failed. Looking at the data line monitor, response times were three times as
long (45 ms)!

It seems strange to me that the USB converter can be so much faster, but I
tried it on a different machine and got very similar (more or less exact)
results. A 266Mhz Win2000 computer works fine with both native serial and
USB to Serial converter, so it seems to be XP itself, as my XP machines are
running closer to 2.6Ghz. I am really wondering if the Keyspan driver is
just faster, or if WinXP just gives more priority to USB???

Steve

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Loren Wilton
Sent: Thursday, December 23, 2004 9:31 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Serial Driver not feeding UART Timely?

Unfortunately if he is speaking to something that uses the ^&*)& “Sony 9-pin
protocol” he is stuck with a 9ms timeout between characters that will
automatically (and almost always incorrectly) terminate a transmission.

Unless of course the implementers of the device were smart and ignored the
9ms requirement in the protocol spec. Doesn’t sound like that is the case
here though.

In any case I deal with idiot devices like that very commonly, and almost
never have problems, unless they also specify idiotically tight turnaround
requirements too. The trick is to keep the thread priority up, use async
IO, set the timeouts correctly, and send and receive strings rather than
individual characters whenever possible.

Loren

I’m not surprised at the differentials in the thread priorities, but I’m
afraid you still have things screwed up somewhere in your code.

I have DLL code that takes MIDI output from programs and spits it to serial
ports at 38400, and MIDI cares about things like 1ms of jitter. On my old
test boxes with real serial ports I can set up a test with periodic outputs
and see that my jitter is well under 1ms when sending 3 byte MIDI packets.

So that means that path length from when I submit the WriteFile with 3 bytes
to when it comes out is pretty short, although that is a little hard to
measure directly. Although I guess I could set up a wraparound test and
measure latency from a 3 byte serial input to a 3 byte serial output on the
same or another port. I’d expect it to be on the order of 1100us or less at
38400, with most of that time the time to receive the 3 bytes.

Now, it could be your boxes have royally screwed up hardware serial ports,
but I doubt that a little. There were some such boxes, but that was long
ago (as far as I know). I certainly haven’t run into one myself.

I’m still suspecting that you son’t have the serial timeouts and other
options set right on your serial port setup. Getting those wrong can result
in the sort of things you are seeing, where an incomng packet ends up
waiting for a while before it shows up.

Oh! I just remembered - it could also be how you are doing your receives.
You should do a receive with an essentially infinite timeout for a SINGLE
byte. When that is satisfied, check to see how many bytes are available in
the buffer, and do a read for exactly that many bytes. If you ask for a 10
byte buffer and only 3 bytes are available, the read won’t complete until
the inter-character delay times out. (There is another way to do this with
a single read and the right timeouts and some other op, but I’ve forgotten
exactly how, and I’m too lazy to go pull the code out of the archive
server.)

As for USB serial devices, most all of them on receive actually generate
packet delays. They try to glob up several characters before putting a
packet on the USB line to keep the USB traffic down, since they all send in
bulk mode. Some of them have interfaces that you can call to remove this
globbing function and send characters when they appear. One interface I
worked with had a globbing delay around 40ms as best I recall, but it could
be set to zero or to a much longer interval.

Let’s see. On reading your reply again, I think your basic problem in
turnaround time, right? You have to get a response back to the thing within
X ms or it times out? So if that is the case, you have two potential
problems - globbing delays on the input path, and any possible delays on the
output path.

For the output path, you should essentially have zero delay on a hardware
serial port… When you send a byte it should show up on the wire within
microseconds. Ideally there won’t be a globbing delay with a USB device,
but there could be. If you are set up to watch modem signals like CTS, then
there are delays in monitoring them. I’m hoping your device doesn’t use
flow control, so you should be able to set up the serial port options to
ignore hardware flow control.

For the input path, there is any globbing delay in the USB device, plus any
inter-character delay that you have set up when you set the serial port
timeouts. (And there is some value set by default, although I don’t remember
what. You need to override it.)

It sounds to me like you may have had a priority problem on the output
thread that you fixed (or got around) with priorities. I think you still
have problems on the input side. Part of this might be asking for X bytes
when only globbing delays.

BTW, as this is a DOS conversion, I hope you don’t have anything running in
a buzz loop looking for input, or for things to do? If so, that could be a
BIG part of your problems. If you have this, you should spend a little time
on whatever is in the buzz loop and redo it to wait on events rationally.

Loren

> I’m still suspecting that you son’t have the serial timeouts and other

options set right on your serial port setup. Getting those wrong can
result in the sort of things you are seeing, where an incomng packet ends
up waiting for a while before it shows up.

In a previous project I used a DLL for my serial I/O, and everything worked
fine, so I used it again. Something could be wrong with the setup, but, I
know this commercial library has been developed for a good while and
implemented under a wide number of circumstances. But poking into its
source, I see the something resembling the following:

COMMTIMEOUTS to;

to.ReadIntervalTimeout = MAXDWORD;
to.ReadTotalTimeoutMultiplier = 0;
to.ReadTotalTimeoutConstant = 0;
to.WriteTotalTimeoutMultiplier = 0;
to.WriteTotalTimeoutConstant = 0;

Which to my understanding means ReadFile will return immediately or times
out immediately. Seems OK to me, but obviously I am not very inexperienced
in this area…

About the receives: I did have a thread running a continuous loop checking
if the input buffer was greater than 0 – while it is > 0 it reads and
processes a character at a time. Realizing this may be sampling overkill, I
found a function in the DLL I’m using which halts until a character is
received. I believe this is an implementation of WaitForSingleObject. So
theoretically no extra processing time is wasting on checking nor waiting
for bytes that have yet to come in… It probably improves the efficiently
of the program but it did not fix or even (as it seems) improve the problem.

Let’s see. On reading your reply again, I think your basic problem in
turnaround time, right? You have to get a response back to the thing
within X ms or it times out?

Yup.

BTW, as this is a DOS conversion, I hope you don’t have anything running
in a buzz loop looking for input, or for things to do? If so, that could
be a BIG part of your problems. If you have this, you should spend a
little time on whatever is in the buzz loop and redo it to wait on events
rationally.

Ah, not familiar with what a buzz loop is… Sorry I guess I’m still too wet
behind the ears! What I took out of that was replacing the blind “check rx
buffer” loop with a rational “wait for rx event before continuing” function
nested in a larger continuous loop. However, there are some tight loops in
the main processing thread that wait for counters to increment from a timer
tread… these loops could probably be replaced with something more
efficient.

Thank you for the help. From your response there are a few more things I can
look into.

Steve

A shot in the dark here. The usb driver can send chunks of data to be
written to the hw over the usb bus. Once onto the device, the device
has no other devices to deal with vs a UART on the ISA bus which will
contend with other devices on the backplane. Basically, the usb device
can just pump more data b/c it is more autonomous. It probably also has
deeper FIFOs on both ends b/c it must wait for the usb host to read the
data in a slower time then an ISA UART based would.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Stephen
Sent: Tuesday, January 11, 2005 3:10 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Serial Driver not feeding UART Timely?

Thanks for that Loren. The hardware in question was designed to speak
with
another piece of hardware, which is what I need to now emulate through a
PC
on WinXP (it was first written for DOS). Changing the hardware is not an
option. Anyway, I did manage to get some better response time by
fiddling
with the thread priorities; I actually had to bring one BelowNormal and
another AboveNormal, as High was too High…

Anyway, I realized that in development I was using a Keyspan Serial to
USB
Link when I got the software working. Response times were adequate: 13ms
between last byte received and first byte sent out. So I tried directly
connecting to the serial port (which was behind the computer and thus
why I
elected to use USB in first place!) and to my surprise the
communications
failed. Looking at the data line monitor, response times were three
times as
long (45 ms)!

It seems strange to me that the USB converter can be so much faster, but
I
tried it on a different machine and got very similar (more or less
exact)
results. A 266Mhz Win2000 computer works fine with both native serial
and
USB to Serial converter, so it seems to be XP itself, as my XP machines
are
running closer to 2.6Ghz. I am really wondering if the Keyspan driver is
just faster, or if WinXP just gives more priority to USB???

Steve

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Loren Wilton
Sent: Thursday, December 23, 2004 9:31 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Serial Driver not feeding UART Timely?

Unfortunately if he is speaking to something that uses the ^&*)& “Sony
9-pin
protocol” he is stuck with a 9ms timeout between characters that will
automatically (and almost always incorrectly) terminate a transmission.

Unless of course the implementers of the device were smart and ignored
the
9ms requirement in the protocol spec. Doesn’t sound like that is the
case
here though.

In any case I deal with idiot devices like that very commonly, and
almost
never have problems, unless they also specify idiotically tight
turnaround
requirements too. The trick is to keep the thread priority up, use
async
IO, set the timeouts correctly, and send and receive strings rather than
individual characters whenever possible.

Loren


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Try to use System Internals PortMon (http://www.sysinternals.com/ntw2k/freeware/portmon.shtml) to see how exactly the DLL communicates with serial port. It shows and decodes most call including port settings. BTW, using serial line directly via Win32 APIs is easy and I see no reason to use a third party DLL.

As for feeding UART, I never noticed a problem with it even at highest speeds. It may be necessary to write data blocks and not single bytes; PortMon would show what your DLL does.

(sorry if I misunderstood something, I haven’t read whole thread back)

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Stephen[SMTP:xxxxx@ecspi.com]
Reply To: Windows System Software Devs Interest List
Sent: Wednesday, January 12, 2005 6:30 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Serial Driver not feeding UART Timely?

> I’m still suspecting that you son’t have the serial timeouts and other
> options set right on your serial port setup. Getting those wrong can
> result in the sort of things you are seeing, where an incomng packet ends
> up waiting for a while before it shows up.

In a previous project I used a DLL for my serial I/O, and everything worked
fine, so I used it again. Something could be wrong with the setup, but, I
know this commercial library has been developed for a good while and
implemented under a wide number of circumstances. But poking into its
source, I see the something resembling the following:

COMMTIMEOUTS to;

to.ReadIntervalTimeout = MAXDWORD;
to.ReadTotalTimeoutMultiplier = 0;
to.ReadTotalTimeoutConstant = 0;
to.WriteTotalTimeoutMultiplier = 0;
to.WriteTotalTimeoutConstant = 0;

Which to my understanding means ReadFile will return immediately or times
out immediately. Seems OK to me, but obviously I am not very inexperienced
in this area…

About the receives: I did have a thread running a continuous loop checking
if the input buffer was greater than 0 – while it is > 0 it reads and
processes a character at a time. Realizing this may be sampling overkill, I
found a function in the DLL I’m using which halts until a character is
received. I believe this is an implementation of WaitForSingleObject. So
theoretically no extra processing time is wasting on checking nor waiting
for bytes that have yet to come in… It probably improves the efficiently
of the program but it did not fix or even (as it seems) improve the problem.

> Let’s see. On reading your reply again, I think your basic problem in
> turnaround time, right? You have to get a response back to the thing
> within X ms or it times out?

Yup.

> BTW, as this is a DOS conversion, I hope you don’t have anything running
> in a buzz loop looking for input, or for things to do? If so, that could
> be a BIG part of your problems. If you have this, you should spend a
> little time on whatever is in the buzz loop and redo it to wait on events
> rationally.

Ah, not familiar with what a buzz loop is… Sorry I guess I’m still too wet
behind the ears! What I took out of that was replacing the blind “check rx
buffer” loop with a rational “wait for rx event before continuing” function
nested in a larger continuous loop. However, there are some tight loops in
the main processing thread that wait for counters to increment from a timer
tread… these loops could probably be replaced with something more
efficient.

Thank you for the help. From your response there are a few more things I can
look into.

Steve


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@upek.com>
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hi

For USB to Serial converters
I have noticed the follow in some drivers if you are using overlapped IO

  1. the WaitForSingleObject(…) does not work. Actually the driver hungs.
    Use instead GetOverlappedResult(…)
    2.If you are using Hardware flow control the driver may hung.

This happens with certain drivers.

regards

micro USB TNT (A pocket TNC with Build in Tracker and APRS digi with USB and
battery for portable operation)
www.elcom.gr

(SV2AGW)George Rossopoulos
xxxxx@elcom.gr
www.elcom.gr/sv2agw
+306932465216
George Rossopoulos
Nikanoros 59
54250,Thessaloniki
Greece

Thanks everyone for their replies.

In order to remove all variables, I wrote simple app using the basic
ReadFile, WriteFile, WaitCommEvent, etc. functions, which does nothing more
than respond with some dummy data the instant it receives something. The USB
converter gives about 3ms (about 3-4x faster than before) turnaround, while
the serial port still gives about 40ms.

Anyway, I tested this on two different Dell WinXP machines with very similar
results. Does anyone know if these things (Dells) have problems with serial
ports? At this point it wouldn’t surprise me, but, I keep thinking there has
to be a more reasonable answer. I fiddled around with just about all the
settings in the Com Port properties but nothing affected the turnaround. The
only non-Dell’s I have right now are Win2000 machines; I’ll be able to test
a ThinkPad tomorrow, I am actually quite anxious to see the results.

Steve