I am having trouble reading data from the serial port. If I call read(), the call is blocked
until the number of bytes specified are available. This is fine for terminal-based I/O, which I
use in certain circumstances where I'll just read one character at a time (typed by a user on
HyperTerm for example). But now I want to read raw data coming from another program over the
serial port.
The problem I'm having is:
A call to ioctl() with the FIONREAD command tells me how much data is in the input buffer, which
appears to be working just fine. Now I want to read that data, but calling read() just blocks
indefintely, never returning the data that's supposed to be in the buffer.
Can anyone tell me why this isn't working, and what I must do to make it work correctly?
Thanks,
Dennis
It would be a little easier if code was posted. Are you saying that you do
an ioctl() that returns n bytes available, and when you attempt to read n
bytes, it blocks? That is certainly the way I've done it before.
What about something like this:
fd_set rd; int s; struct timeval t;
t.tv_sec = t.tv_usec = 0;
s = fileno(stdin);
FD_SET(s, &fd);
if (select(soc+1, &fd, NULL, NULL, &t) > 0) read(...);
else /* No data this time!
Is your serial port set up for raw I/O? If not, the driver may be pending
for a carriage return.
You can use an ioctl() to set the serial port for raw I/O after it has been
opened:
status = ioctl (fd, FIOOPTIONS, OPT_RAW);
HTH
Charlie Grames
The Boeing Company
(314) 233-1956
Charles....@boeing.com
Newsgroups: comp.os.vxworks
Subject: reading from serial port
Date: Mon, 10 May 1999 21:21:20 GMT
From: Dennis Jones <dennis....@tektronix.com>
Organization: Tektronix, Inc.
Message-ID: <37374D47...@tektronix.com>
Dennis Jones wrote:
Help!I am having trouble reading data from the serial port. If I call read(), the call is blocked
until the number of bytes specified are available. This is fine for terminal-based I/O, which I
use in certain circumstances where I'll just read one character at a time (typed by a user on
HyperTerm for example). But now I want to read raw data coming from another program over the
serial port.The problem I'm having is:
A call to ioctl() with the FIONREAD command tells me how much data is in the input buffer, which
appears to be working just fine. Now I want to read that data, but calling read() just blocks
indefintely, never returning the data that's supposed to be in the buffer.Can anyone tell me why this isn't working, and what I must do to make it work correctly?
Thanks,
Dennis
What you have decribed here sounds very similar to something that
I needed to do. For our application, we are using the console port,
and did not want the characters echoed to the terminal, or to be blocked.
To accomplish this, I set up the serial port with the following:
IStatus = ioctl ( STD_IN, FIOSETOPTIONS, OPT_TERMINAL & ~OPT_LINE & ~OPT_ECHO );
After this initialization, I read the serial port character by character.
char *COMMAND_Char;
*COMMAND_Char = getchar ();
The getchar function waits until a character is pressed, but does not "block" until the EOL.
Hope this helps,
--
Peter
-----------------------------------------------
E-mail: funo...@metrolink.net (home)
http://www.geocities.com/Colosseum/Arena/2475/
-----------------------------------------------
A few simple modifications to the serial driver can make the IO very
efficient. The basic idea is to setup a watchdog timer in the driver that is
setup to expire after a few character receive periods elapse on the serial
port at the current baud rate. The watchdog is restarted after each new
character comes in, but select() is not triggered in the driver until one of
two things occurs in the driver:
a) The receive ring buffer is nearly full; or
b) the watchdog expires.
At the task level you block on select() and wait for it to fire off. When
you do the read() you will always get a full ring buffer full of data or
have all the data up to the point in the receive stream where there was an
interruption in the transmission. In other words you never have to worry
about the received data becoming "stale", but the data is always moved in as
chunky as a fashion as possible.
Regards,
Jeff
===========================
Jeffrey R. Szczepanski < j...@inscitek.com>
InSciTek Microsystems, Inc.
635 CrossKeys Office Park
Fairport, NY 14450
< www.inscitek.com>
Phone: 716-421-3850
Bruce wrote in message <37377d10...@news.texas.net>...
>In comp.os.vxworks
>Dennis Jones <dennis....@tektronix.com> wrote:
>
>>I am having trouble reading data from the serial port. If I call read(),
the call is blocked
>>until the number of bytes specified are available. This is fine for
terminal-based I/O, which I
>>use in certain circumstances where I'll just read one character at a time
(typed by a user on
>>HyperTerm for example). But now I want to read raw data coming from
another program over the
>>serial port.
>>
>>The problem I'm having is:
>>
>>A call to ioctl() with the FIONREAD command tells me how much data is in
the input buffer, which
>>appears to be working just fine. Now I want to read that data, but
calling read() just blocks
>>indefintely, never returning the data that's supposed to be in the buffer.
>
>>Can anyone tell me why this isn't working, and what I must do to make it
work correctly?
>
Bruce wrote:
>
> In comp.os.vxworks
> Dennis Jones <dennis....@tektronix.com> wrote:
>
> >I am having trouble reading data from the serial port. If I call read(), the call is blocked
> >until the number of bytes specified are available. This is fine for terminal-based I/O, which I
> >use in certain circumstances where I'll just read one character at a time (typed by a user on
> >HyperTerm for example). But now I want to read raw data coming from another program over the
> >serial port.
> >
> >The problem I'm having is:
> >
> >A call to ioctl() with the FIONREAD command tells me how much data is in the input buffer, which
> >appears to be working just fine. Now I want to read that data, but calling read() just blocks
> >indefintely, never returning the data that's supposed to be in the buffer.
>
> >Can anyone tell me why this isn't working, and what I must do to make it work correctly?
>
> It would be a little easier if code was posted. Are you saying that you do
> an ioctl() that returns n bytes available, and when you attempt to read n
> bytes, it blocks? That is certainly the way I've done it before.
That's exactly right. Basically, I do something like this:
ioctl( fd, FIONREAD, &n );
read( fd, data, n );
I have tried:
ioctl( fd, FIOSETOPTIONS, OPT_RAW ) to make sure the port is in RAW
mode, but this does not help.
If another task has an open file descriptor on the port, would that
result in the kind of behavior I'm seeing?
Some more background may be in order:
I want to have exclusive access to the port while my task is running. I
know it is safe to do so, but I think another task already has an open
file descriptor for the port. I need to prevent that task from using
the port while my task executes. This necessitates (I think) some way
of determining: a) if the port is, in fact, already in use, and b) which
task is using it (so I can suspend it temporarily).
My task should start out using the port in the normal terminal mode, and
should switch to raw mode upon receipt of a special character (which
I've defined to be 0x80). After I'm through with it, it should switch
back to terminal mode, at which time I will need to give up the port so
other tasks (if any) can use it.
Does this make sense, and is it a reasonable process?
Thanks for the replies so far. I'm a VxWorks newbie and sure do
appreciate your generous responses.
Dennis Jones
Tektronix, Inc.