Re: reading from a serial port
From: Floyd L. Davidson (floyd_at_barrow.com)
Date: 08/01/04
- Next message: Richard L. Hamilton: "Re: Question on Unix FIFOs - why slow when on NFS?"
- Previous message: maxw_cc: "Re: reading from a serial port"
- In reply to: maxw_cc: "Re: reading from a serial port"
- Next in thread: maxw_cc: "Re: reading from a serial port"
- Reply: maxw_cc: "Re: reading from a serial port"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sat, 31 Jul 2004 22:00:44 -0800
maxw_cc@yahoo.com (maxw_cc) wrote:
>floyd@barrow.com (Floyd L. Davidson) wrote in message news:<87acxh5kih.fld@barrow.com>...
>> "High level" i/o uses the Standard IO Library for C, which hides
>> the kernel from the programmer, and rather than an index into an
>> array of structs, it uses a pointer to one element in an array
>> structures to deal with data streams rather than directly with
>> open files. It is an abstraction built on top of the low level
>> file access. That allows the C programming language to provide
>> the same file interface to the programmer on every platform,
>> including those which have an entirely different concept of low
>> level i/o.
>>
>
>Floyd, could you please give more information/details on how this is
>implemented in the C library. Unfortunately :( my knowledge only goes
>far enough to know that FILE is possibly a typedef to some struct.
>Could you please explain a little bit more (give details) of what you
>say:
>
>>"it uses a pointer to one element in an array
>> structures to deal with data streams rather than directly with
>> open files."
>
>I didn't know it was implemented as an array of structures, I assume
>you refer to something like FILE *fp[]; But I don't know :(
>I always like reading your posts, I always learn a lot, and I will
>certainly appreciate it if you could please give me more details on
>this subject.
Well... Let me try...
The STDIO library was initially not actually part of the C
language, but was an "add on" library of "functions designed to
provide a standard I/O system for C programs." (K&R, 1st
Edition, p143).
The stdio library is written specifically for each platform,
hence we can't really use Linux, BSD, Solaris and other real
platform as an example and expect the specifics to be the same
with all of the others. That applies for example to the FILE
struct, which is defined differently for each (though granted
they are all very similar). Plus the complexity of real world
implementations can obscure the basics.
Hence I'm going to use simplified examples from Kernighan and
Ritchie, "The C Programming Language", 2nd Edition. I would
*highly* advise that you obtain a copy! Likewise a copy of
Richard W. Stevens, "Advanced Programming in a Unix Environment"
is also indispensable.
In order to provide a uniform interface to different devices,
the stdio library allocates a data buffer (BUFSIZ in stdio.h is
the size) and all of the functions operate on data in that
buffer. The underlying functions automatically flush the buffer
or refresh it with new data as required to service the functions
called by a program. Hence when your program calls fopen() and
then read or writes data, a data buffer and a FILE struct are
assigned to the file or device that is opened.
The example that K&R used (which would be found in stdio.h),
looks like this
typedef struct _iobuf {
int cnt; /* characters left */
char *ptr; /* next character position */
char *base; /* location of buffer */
int flag; /* mode of file access */
int fd; /* file descriptor */
} FILE;
Several #defines are used in conjunction with a FILE struct,
two that have obvious uses are,
#define OPEN_MAX 20 /* max # of files open at once */
#define BUFSIZ 1024
And there are definitions for the flag values,
enum _flags {
_READ = 1; /* file open for reading */
_WRITE = 2; /* file open for writing */
_UNBUF = 4; /* file is unbuffered */
_EOF = 8; /* EOF has occurred */
_ERR = 16; /* error occurred */
};
The stdio library declares an array of type FILE, and initializes
the first three elements for use as stdin, stdout, and stderr.
The external access to that array is provided in stdio.h,
extern FILE _iob[OPEN_MAX];
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
Now, once you've seen that, a number of STDIO "functions" that
are actually available as macros suddenly become trivial,
#define feof(p) (((p)->flag & _EOF) != 0)
#define ferror(p) (((p)->flag & _ERR) != 0)
#define fileno(p) ((p)->fd)
#define getc(p) (--(p)->cnt >= 0 ? \
(unsigned char) *(p)->ptr++ : \
_fillbuf(p))
#define getchar() getc(stdin)
Note that _fillbuf() is a function that fills the buffer,
correctly sets appropriate values in the FILE struct, and
returns the first character.
While the above example shows BUFSIZ defined as 1024, it is
probably larger than that today on most modern unixes (8k is
common).
Consider the above example in terms of reading from an 8 inch
floppy disk 25 years ago. The disk provided data in 128 byte
blocks, but the stdio library would grab data in chunks 8 times
that size, and all I/O would be only to the buffer as long as it
stayed within that 1k range. A loop using getc(), for example,
merely fetches a byte from the buffer 1024 times and then
causes another 8 blocks of data to read from the disk. As
opposed to that, if the read() function were used to fetch one
byte at a time, it would actually do a 128 byte sector read
*every time*, and provide the program with one character from
that read. Obviously using the stdio library, in this case,
results in a very significant speed increase.
The speed difference is not nearly as dramatic today, because
not only does the disk buffer sector or track reads, but so
does the OS. Regardless, using stdio functions provides a
standardized interface to I/O for all C programs.
-- FloydL. Davidson <http://web.newsguy.com/floyd_davidson> Ukpeagvik (Barrow, Alaska) floyd@barrow.com
- Next message: Richard L. Hamilton: "Re: Question on Unix FIFOs - why slow when on NFS?"
- Previous message: maxw_cc: "Re: reading from a serial port"
- In reply to: maxw_cc: "Re: reading from a serial port"
- Next in thread: maxw_cc: "Re: reading from a serial port"
- Reply: maxw_cc: "Re: reading from a serial port"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|