Re: serial port question.
- From: floyd@xxxxxxxxxx (Floyd L. Davidson)
- Date: Tue, 30 May 2006 18:33:37 -0800
Chris.Reath@xxxxxxxxx wrote:
Thanks. I definetely know what I need to do with writes.
If you aren't sure about reads, is there some reason to be
positive about writes? You might want to work up an example
program and post it to get comments.
But what about reads? How do I know how much more to read when I am
sent a variable amount of data?
There are a large number of possible solutions, and without
knowing what you are actually doing there is little point in
trying to recommend which approach would be best. For example
you don't say if you have control over both ends of this
connection and can implement your own data framing, or not. The
same is true with timing, where we don't know what parameters
you have to work with.
Generally the best solution is to implement a simple data
framing scheme. Then the safest way to read data is one byte at
a time with a state machine that first reads input and discards
it until a start of frame flag is seen. It collects data until
either an error is encountered or an end of frame flag is found.
Errors can be handled in many ways, but one would be to just
start over again. An end of frame flag invokes whatever is
required to process the frame and then starts the process again.
But in many cases it is not possible to frame data other than by
timed intervals. In that case the usual sequence is to send
data first, then begin looking for incoming data. After a
specified interval, if no data is received it is assumed none is
going to be sent. If any data is received, reading the input is
continued until no data is received for some specified interval,
at which point the currently buffered data is processed and the
cycle is restarted.
Here is some example code for timed reads. Note that this
assumes O_NONBLOCK has not been set, and that the termios
c_cc[VTIME] element is set to some value greater than 0 while
c_cc[VMIN] is 0. Be warned that this code is untested and is
just something I threw together for an article posted to answer
a question in comp.os.linux.development.apps about a week ago.
/* these values must be larger than 10 */
#define PRE_TIMEOUT 5000 /* maximum milliseconds before data */
#define POST_TIMEOUT 100 /* minimum milliseconds after data */
#include <time.h>
unsigned int
get_data(int fd, char *buf, int size)
{
int bytes, cnt = 0, timerflag = 0;
unsigned int offset;
struct timespec tv;
tv.tv_sec = 0;
tv.tv_nsec = 10000 /* 10 ms, minimum granularity on some systems */
while (1) {
/* quite when we have enough data */
if (size < 1) {
break;
}
/* pre data timer */
if (!timerflag && cnt >= PRE_TIMEOUT / (tv.tv_nsec / 1000)) {
break;
}
/* post data timer */
if (timerflag && cnt >= POST_TIMEOUT / (tv.tv_nsec / 1000)) {
break;
}
if (0 > (bytes = read(fd, buf + offset, 1))) {
return -1;
}
if (bytes > 0) {
timerflag = 1;
cnt = 0;
--size;
++offset;
continue;
}
++cnt;
nanosleep(*tv, NULL);
}
return offset;
}
Another possible approach is asynchronous reads and writes.
Using threads or forking processes, or a polling loop, or
interrupt driven asynchronous input. Obviously that is more
complex that the synchronous write then read cycle described
above.
Here is a URL to several examples of different ways to write
and read data to a serial port. These example programs implement
a test program that can talk to a typical modem; however, they
can all easily be modified to talk to any serial device. They
are all limited to simply processing a continuous stream of data
from the device by merely printing it on the screen. Hence if
a complete packet is needed before processing is started that
functionality would need to be added.
http://www.apaflo.com/floyd_davidson//code/terminal/
--
Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) floyd@xxxxxxxxxx
.
- Follow-Ups:
- Re: serial port question.
- From: Chris . Reath
- Re: serial port question.
- References:
- serial port question.
- From: Chris . Reath
- Re: serial port question.
- From: Henrik Carlqvist
- Re: serial port question.
- From: Chris . Reath
- serial port question.
- Prev by Date: Re: agpgart after install?
- Next by Date: Looking for hardware recommendations...
- Previous by thread: Re: serial port question.
- Next by thread: Re: serial port question.
- Index(es):