Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems reading and writing serial ports.

Status
Not open for further replies.

CaKiwi

Programmer
Apr 8, 2001
1,294
US

I am having problems reading and writing to serial ports using gcc under Mandrake Linux v 8.1. I have a cable connecting com1 and com2 and I write 16 characters to com1. If I read com2 immediately I get no characters returned but if I delay
4 or more seconds before reading I get 4096 characters returned - my 16 characters repeated followed by 1, 2, 4, 8, 16, etc linefeeds. Any help would be greatly appreciated.
Code:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>

int main(void)
{
	int fd0, fd1, knt, n;
	char coma[2];
	struct termios option0, option1;

// Open and set up ttyS0
	fd0 = open(&quot;/dev/ttyS0&quot;, O_RDWR | O_NOCTTY);
	if (fd0 == -1) return(-1);
	tcgetattr(fd0, &option0);
	cfsetispeed(&option0, B19200);
	cfsetospeed(&option0, B19200);
	option0.c_cflag |= (CLOCAL | CREAD);
	option0.c_cflag &= ~PARENB;
	option0.c_cflag &= ~CSTOPB;
	option0.c_cflag &= ~CSIZE;
	option0.c_cflag |= CS8;
	option0.c_oflag = 0;
	option0.c_lflag |= ~(ICANON | ECHO | ISIG);
	tcflush(fd0, TCIFLUSH);
	tcsetattr(fd0, TCSANOW, &option0);
// Open and set up ttyS1
	fd1 = open(&quot;/dev/ttyS1&quot;, O_RDWR | O_NOCTTY | O_NDELAY);
	if (fd1 == -1) return(-1);
	tcgetattr(fd1, &option1);
	cfsetispeed(&option1, B19200);
	cfsetospeed(&option1, B19200);
	option1.c_cflag |= (CLOCAL | CREAD);
	option1.c_cflag &= ~PARENB;
	option1.c_cflag &= ~CSTOPB;
	option1.c_cflag &= ~CSIZE;
	option1.c_cflag |= CS8;
	option1.c_lflag |= ~(ICANON | ECHO | ISIG);
	option1.c_cc[VTIME] = 10;
	option1.c_cc[VMIN]  = 0;
	tcflush(fd1, TCIFLUSH);
	tcsetattr(fd1, TCSANOW, &option1);
// Write to ttyS0
	n = write(fd0,&quot;ABCABCABCABCABC\n&quot;,16);
	printf (&quot;Wrote %d characters, ABCABCABCABCABC\\n\n&quot;,n);
// Without this delay, no characters are read, with it 4096 are read.
	sleep(4);
	coma[1]=0;
	n = read (fd1, coma, 1);
	knt = 1;
	while (n >= 0)
	{
		if (coma[0]=='\n') printf(&quot;\\n&quot;);
		else printf (&quot;%s&quot;,coma);
		knt++;
		if (knt%40 == 0) printf(&quot;\n&quot;);
		n = read (fd1, coma, 1);
	}
	printf (&quot;\nknt = %d, n = %d\n&quot;,knt,n);
	close(fd0);
	close(fd1);
	return (0);
}
CaKiwi
 
In case anyone cares, the problem turned out to be the setting of the lflag member of the option structure. I am not sure why this is and would be interested if anyone has an explanation. I also changed the open statement to make the timeout on read work. Here is the final program with the significant changes highlighted.
[tt]
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>

int main(void)
{
int fd0, fd1, knt, n;
char coma[2];
struct termios option0, option1;

// Open and set up ttyS0
fd0 = open(&quot;/dev/ttyS0&quot;, O_RDWR );
if (fd0 == -1) return(-1);
tcgetattr(fd0, &option0);
cfsetispeed(&option0, B19200);
cfsetospeed(&option0, B19200);
option0.c_cflag |= (CLOCAL | CREAD);
option0.c_cflag &= ~PARENB;
option0.c_cflag &= ~CSTOPB;
option0.c_cflag &= ~CSIZE;
option0.c_cflag |= CS8;
option0.c_oflag = 0;
option0.c_lflag = 0;
tcflush(fd0, TCIFLUSH);
tcsetattr(fd0, TCSANOW, &option0);
// Open and set up ttyS1
fd1 = open(&quot;/dev/ttyS1&quot;, O_RDWR | O_NOCTTY);
if (fd1 == -1) return(-1);
tcgetattr(fd1, &option1);
cfsetispeed(&option1, B19200);
cfsetospeed(&option1, B19200);
option1.c_cflag |= (CLOCAL | CREAD);
option1.c_cflag &= ~PARENB;
option1.c_cflag &= ~CSTOPB;
option1.c_cflag &= ~CSIZE;
option1.c_cflag |= CS8;
option1.c_lflag = 0;
option1.c_cc[VTIME] = 50;
option1.c_cc[VMIN] = 0;
tcflush(fd1, TCIFLUSH);
tcsetattr(fd1, TCSANOW, &option1);
// Write to ttyS0
n = write(fd0,&quot;ABCABCABCABCABC\r&quot;,16);
printf (&quot;Wrote %d characters, ABCABCABCABCABC\\n\n&quot;,n);

coma[1]=0;
n = read (fd1, coma, 1);
knt = 0;
while (n > 0)
{
if (coma[0]=='\n') printf(&quot;\\n&quot;);
else printf (&quot;%s&quot;,coma);
knt++;
if (knt%40 == 0) printf(&quot;\n&quot;);
n = read (fd1, coma, 1);
}
printf (&quot;\nknt = %d, n = %d\n&quot;,knt,n);
close(fd0);
close(fd1);
return (0);
}
CaKiwi
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top