Reading data from serial port on Linux using a C program

V

Vivek Menon

Hi,
I am using a C program to write/read from a serial port. The writing
part is working perfectly fine. However, I am not able to read the
values correctly and display them. To debug this issue I am also seeing
the values on minicom. Now I have used fcntl() function and then read
refp = fcntl(fd, F_SETFL, 0);
res = read(fd,buf,1024); /* Read the value sent on the serial port
buf[res]=0; /* set end of string, so we can printf */
printf(":%s:%d\n", buf, res);

On minicom I see about more than 256 characters. I need to store all of
them as a string and then process that string. However when I run the
program, the printf statement only displays 8 or 16 characters.
Is there a fix for this issue??
BTW I have used both Canonical and non-canonical processing without any
evident results.
Thanks,
Vivek
 
W

Walter Roberson

Vivek Menon said:
I am using a C program to write/read from a serial port. The writing
part is working perfectly fine. However, I am not able to read the
values correctly and display them. To debug this issue I am also seeing
the values on minicom. Now I have used fcntl() function and then read
refp = fcntl(fd, F_SETFL, 0);
res = read(fd,buf,1024); /* Read the value sent on the serial port
buf[res]=0; /* set end of string, so we can printf */
printf(":%s:%d\n", buf, res);

Sorry, fcntl() and read() are not part of the C language itself.
For information about their workings, you need to consult an
information source that is more specific to your platform, such as
comp.unix.programming

On minicom I see about more than 256 characters. I need to store all of
them as a string and then process that string. However when I run the
program, the printf statement only displays 8 or 16 characters.
Is there a fix for this issue??

[Off Topic]
In POSIX systems, it is legal and common for read() of a tty
to only return a relatively small number of characters. To get all
of the characters, you need to loop until you detect that you have
read enough or that you have reached end of file.
 
I

Insik Park

Vivek said:
Hi,
I am using a C program to write/read from a serial port. The writing
part is working perfectly fine. However, I am not able to read the
values correctly and display them. To debug this issue I am also seeing
the values on minicom. Now I have used fcntl() function and then read
refp = fcntl(fd, F_SETFL, 0);
res = read(fd,buf,1024); /* Read the value sent on the serial port
buf[res]=0; /* set end of string, so we can printf */
printf(":%s:%d\n", buf, res);

On minicom I see about more than 256 characters. I need to store all of
them as a string and then process that string. However when I run the
program, the printf statement only displays 8 or 16 characters.
Is there a fix for this issue??
BTW I have used both Canonical and non-canonical processing without any
evident results.
Thanks,
Vivek

Try putting the call to "read" inside of a loop. For example:

int num, offset = 0, bytes_expected = 256;
do {
num = read(fd, buf + offset, 1024);
offset += num;
} while (offset < bytes_expected);
From the Linux man pages:
"It is not an error if this number is smaller than the number of bytes
requested; this may happen for example because fewer bytes are actually
available right now (maybe because we were close to end-of-file, or
because we are reading from a pipe, or from a terminal), or because
read() was interrupted by a signal. "

Of course if you aren't always going to be receiving 256 bytes, then
the sending app will have to tell the receiving app how many bytes to
expect (most likely sent as a header through the serial interface!).
 
K

Keith Thompson

Vivek Menon said:
I am using a C program to write/read from a serial port.
[...]

Standard C has no support for serial ports. You'll need to ask in a
system-specific newsgroup, perhaps comp.unix.programmer.
 
V

Vivek Menon

Thanks for the insight.
I used the loop you mentioned and the program hangs because the number
of characters output changes every time.
Instead I used:
==================
while (STOP==FALSE) {
res = read(fd,buf,255);
buf[res]=0; /* set end of string, so we can
printf */
printf(":%s:%d\n", buf, res);
if (buf[0]=='\0') STOP=TRUE;
}
===========
My program output:
:000020822186228A:16
:35D736DB37DF38E4:16
:3BF03CF43DF83EFC:16
:20822186:8
:36DB37DF:8
:3CF43DF8:8
:D7000000:8
and then this hangs too...

My minicom output:
9E83AEC3BF03CF43DF83EFC4000772221BE9B0000000000A745001141E10000020822186228A238E249235D736DB37DF38E439E83AEC3BF03CF43DF83EFC400077282808890000B3
====
I have checked for eof, '\0' and '\n' on the terminal(minicom) and all
these conditions do not seem to work. The number of characters change,
so I cannot use a fixed count value.
Any suggestions
Thanks,
Vivek

Insik said:
Vivek said:
Hi,
I am using a C program to write/read from a serial port. The writing
part is working perfectly fine. However, I am not able to read the
values correctly and display them. To debug this issue I am also seeing
the values on minicom. Now I have used fcntl() function and then read
refp = fcntl(fd, F_SETFL, 0);
res = read(fd,buf,1024); /* Read the value sent on the serial port
buf[res]=0; /* set end of string, so we can printf */
printf(":%s:%d\n", buf, res);

On minicom I see about more than 256 characters. I need to store all of
them as a string and then process that string. However when I run the
program, the printf statement only displays 8 or 16 characters.
Is there a fix for this issue??
BTW I have used both Canonical and non-canonical processing without any
evident results.
Thanks,
Vivek

Try putting the call to "read" inside of a loop. For example:

int num, offset = 0, bytes_expected = 256;
do {
num = read(fd, buf + offset, 1024);
offset += num;
} while (offset < bytes_expected);
From the Linux man pages:
"It is not an error if this number is smaller than the number of bytes
requested; this may happen for example because fewer bytes are actually
available right now (maybe because we were close to end-of-file, or
because we are reading from a pipe, or from a terminal), or because
read() was interrupted by a signal. "

Of course if you aren't always going to be receiving 256 bytes, then
the sending app will have to tell the receiving app how many bytes to
expect (most likely sent as a header through the serial interface!).
 
C

CBFalconer

Keith said:
Vivek Menon said:
I am using a C program to write/read from a serial port.
[...]

Standard C has no support for serial ports. You'll need to ask
in a system-specific newsgroup, perhaps comp.unix.programmer.

However they are often mapped into a FILE* stream. Again, this is
system dependent.
 
V

Vivek Menon

Thanks for your suggestion, but the '/r' condition makes the program as
usual.
Any other suggestions??
I tried checking eof condition when res =0. That does not work too..
I am now trying to write these values directly to another file and see
what happens. No success so far.
Vivek

Insik said:
Vivek said:
Hi,
I am using a C program to write/read from a serial port. The writing
part is working perfectly fine. However, I am not able to read the
values correctly and display them. To debug this issue I am also seeing
the values on minicom. Now I have used fcntl() function and then read
refp = fcntl(fd, F_SETFL, 0);
res = read(fd,buf,1024); /* Read the value sent on the serial port
buf[res]=0; /* set end of string, so we can printf */
printf(":%s:%d\n", buf, res);

On minicom I see about more than 256 characters. I need to store all of
them as a string and then process that string. However when I run the
program, the printf statement only displays 8 or 16 characters.
Is there a fix for this issue??
BTW I have used both Canonical and non-canonical processing without any
evident results.
Thanks,
Vivek

Try putting the call to "read" inside of a loop. For example:

int num, offset = 0, bytes_expected = 256;
do {
num = read(fd, buf + offset, 1024);
offset += num;
} while (offset < bytes_expected);
From the Linux man pages:
"It is not an error if this number is smaller than the number of bytes
requested; this may happen for example because fewer bytes are actually
available right now (maybe because we were close to end-of-file, or
because we are reading from a pipe, or from a terminal), or because
read() was interrupted by a signal. "

Of course if you aren't always going to be receiving 256 bytes, then
the sending app will have to tell the receiving app how many bytes to
expect (most likely sent as a header through the serial interface!).
 
K

Keith Thompson

Vivek Menon said:
Thanks for your suggestion, but the '/r' condition makes the program as
usual.
Any other suggestions??
I tried checking eof condition when res =0. That does not work too..
I am now trying to write these values directly to another file and see
what happens. No success so far.
[snip]

As has already been mentioned, this question (about reading from a
serial port) is off-topic for comp.lang.c. (Yes, I know you're doing
it in C, but you're using extensions not defined by the language
standard.) You'll probably find that comp.unix.programmer is full of
helpful people eager to answer all the Unix-specific questions you can
come up with.

But you're more likely to get help there if you avoid top-posting:

http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php
 
B

bogdan

Hi,
I am using a C program to write/read from a serial port. The writing
part is working perfectly fine. However, I am not able to read the
values correctly and display them. To debug this issue I am also seeing
the values on minicom. Now I have used fcntl() function and then read
refp = fcntl(fd, F_SETFL, 0);
res = read(fd,buf,1024); /* Read the value sent on the serial port
buf[res]=0; /* set end of string, so we can printf */
printf(":%s:%d\n", buf, res);

On minicom I see about more than 256 characters. I need to store all of
them as a string and then process that string. However when I run the
program, the printf statement only displays 8 or 16 characters.
Is there a fix for this issue??
BTW I have used both Canonical and non-canonical processing without any
evident results.
Thanks,
Vivek

http://magegame.ru/?rf=626f6764616e
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,709
Latest member
AustinMudi

Latest Threads

Top