Re: Highly responsive serial port
- From: Louis <nospam@xxxxxxxxxx>
- Date: Wed, 06 Aug 2008 02:15:15 -0400
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. :-)
--
.
- References:
- Highly responsive serial port
- From: Arkej
- Highly responsive serial port
- Prev by Date: Re: WDF - User Mode Driver Framework - COM port driver
- Next by Date: Executing an Unmanaged Exe from Memory
- Previous by thread: Re: Highly responsive serial port
- Next by thread: Re: STATUS_ILLEGAL_INSTRUCTION returned by ZwQueryDirectoryFile()
- Index(es):
Relevant Pages
|