Re: Highly responsive serial port



Arkej wrote:

Hello,
before I dive into the world of kernel mode drivers I'd like to know:
My problem consists of reading from a serial COM port as fluent as possible(real-time like). It looks like it is not doable in user mode. If due to scheduling of threads my reader thread doesn't get enough time I have a delay of read on the input. Let's say I have to process data coming every 30ms and then reply in 20ms. If my reader only reads the input buffer after 50ms I'm too late to reply but I don't know it.
1. Would a driver(in kernel mode) have enough priority to process such requests in time?
2. Is there any other way in user mode to assure constant read of serial port?

That is what hardware flow control is used for.

There are two sides to this which I can generalized as follows:

- Receive as fast as you can with high buffers
- Transmit as fast as you can with lower buffers.

This "bucket brigade" concept is simple:

The sender will never know how big or how fast the receiver can handle the sender's pumping of data. If you used high transmit buffer, the odds are very good you will get flow control signals. Its not efficient. In a bucket brigade, one node can not go any faster than the next and you can't fill it any more than bucket can hold. So an efficient brigade is one that is near continuous without stopping.

On the other hand, the receiver is fully aware of what it can handle so it should not be designed to slow down its reception of data - "Give me what you got" attitude, "I can handle whatever you can send."
It should be a draining concept, don't read a few bytes at time. Get it all during that one signal instance. But you need to do this asynchronously and not ask for too much because that can put pressure on the system to fulfill your request.

Most high end com packages traditionally used a three threads per PORT approach:

- a receiver thread using a circular buffer, i.e., 16K

- a sender thread using a circular buffer, i.e, 4K

- a UI thread (passive, main or otherwise), that
can read events from the receiver thread or transmit
thread, or it can be done procedurally.

The receiver/transmit thread might run in a lightly higher priority.

Also, the protocols you might use, i.e, transfer a file with ZMODEM, XMODEM, YMODEM, KERMIT, etc, will help design some of the settings too. For example, ZMODEM can start with 16K windows that can be reduced during the protocol transmission if it finds too many retries. XMODEM on the other hand is a fixed 128 BYTE block concept - very inefficient.

Overall, the key is to make sure you get your flow control right. You need to prepare the port with the right set of hardware flow control flags with the right sizes for buffers and also your timeouts to minimize the number of cycles.

Finally, a general rule of thumb in thread synchronization (especially in a non-RTOS) is to stay away from depending on "sleep" and loop designs in a vain attempt to synchronize I/O. You might get it to work in one environment, but inevitably its going to bite you :-) There are scores of books discussions on the subject. Google it.

Keep in mind these designs pre-dated I/O Comp ports ideas, that may help reduced threads and scalability issues. In my exploration done a few years ago, I found there some efficiency issues - never mind the more complex designs especially with our virtual com I/O model, i.e, I found issues with using the same IOCP model used for sockets, for RS232. Theoretically should work the same but it doesn't. :)

I do want to give it another shot one day, but we have yet to find a good reason to break what isn't broke. :-)

--
.



Relevant Pages

  • Serial Communication in C# Express
    ... ago and I really appreciated Nicholas Paldino's help, ... > I can only achieve to transmit '34', ... After the usual port initialization, ... // Obtain the number of bytes waiting in the port's buffer ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Serial COM port communication problems
    ... serial port. ... The receiving buffer is read by setting the mask to rx flag being the ... sub-packages arrive in succession and some sub-packages are lost. ... But this should not cause a loss of data, assuming you are reading the actual number of characters retured by WaitCommEvent. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Serial Communications - Lost Event
    ... "Completion of write" is a moment when all data from the app buffer is ... The driver can keep the data in its internal buffer ... > serial port monitoring and test applications. ... > of a serial port means when all of the data has been transfered. ...
    (microsoft.public.win32.programmer.kernel)
  • [PATCH] cpm_uart: Fix dpram allocation and non-console uarts
    ... Makes non-console UART work on both 8xx and 82xx ... static unsigned int cpm_uart_tx_empty(struct uart_port *port) ... /* Write back buffer pointer */ ... * Allocate DP-Ram and memory buffers. ...
    (Linux-Kernel)
  • Re: SHOW DEVICE: what should it show?
    ... (SHOW DEVICE also uses direct access into kernel mode, ... > passes a buffer back down to user mode for display, ... > DCL command procedures seeking devices should be using the available ... or minuses allowed in the /INCLUDE list as in the ACCOUNTING utility? ...
    (comp.os.vms)