Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

reading from serial port

1,163 views
Skip to first unread message

Dennis Jones

unread,
May 10, 1999, 3:00:00 AM5/10/99
to
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


Bruce

unread,
May 11, 1999, 3:00:00 AM5/11/99
to
In comp.os.vxworks
Dennis Jones <dennis....@tektronix.com> wrote:

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.


MLS

unread,
May 11, 1999, 3:00:00 AM5/11/99
to

Dennis Jones <dennis....@tektronix.com> wrote in message
news:37374D47...@tektronix.com...
> 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 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!


Charlie Grames

unread,
May 11, 1999, 3:00:00 AM5/11/99
to
Dennis,

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>

Peter

unread,
May 11, 1999, 3:00:00 AM5/11/99
to

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/
-----------------------------------------------
 

Jeff Szczepanski

unread,
May 11, 1999, 3:00:00 AM5/11/99
to
I agree with Charlie Grames..... I think you really want to be running the
serial port in RAW mode using the IOCTL. However, the one problem that you
typically have here is that the serial port is too slow relative to the CPU,
especially at the lower baud rates. ie: Every time you do a read(), you only
get a few characters maximum and moving lots of data can be rather task
switch intensive getting the characters as they trickle in on the serial
port.

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?
>

Dennis Jones

unread,
May 11, 1999, 3:00:00 AM5/11/99
to

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.

0 new messages