LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 07-09-2009, 10:09 AM   #1
nanoo
LQ Newbie
 
Registered: Jul 2009
Posts: 19

Rep: Reputation: 1
Question termios /dev/ttyUSB0 "resource unavailable"


Hi!
I am working on simple project which will extract temperature from microcontroller. It is connected to computer through serial-to-usb chip.
The testing of connection is: I send to mc one char "p" and it answer me with "p\0" (2 bytes). And even with this simple interchange I have encountered a problem.
Code:
#include<stdio.h>
#include<errno.h>
#include<termios.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>

int tty_set(int tty)
{
	struct termios tty_opts;
	int foo;
	
	foo=tcgetattr(tty,&tty_opts);
	if(foo<0) return -1;
	
	foo=cfsetispeed(&tty_opts,B9600);
	if(foo<0) return -2;
	
	foo=cfsetospeed(&tty_opts,B9600);
	if(foo<0) return -3;
	
	//3
	// 8N1
	tty_opts.c_cflag &= ~PARENB;
	tty_opts.c_cflag &= ~CSTOPB;
	tty_opts.c_cflag &= ~CSIZE;
	tty_opts.c_cflag |= CS8;
	// no flow control
	tty_opts.c_cflag &= ~CRTSCTS;

	tty_opts.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
	tty_opts.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl

	tty_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
	tty_opts.c_oflag &= ~OPOST; // make raw

	// see: http://unixwiz.net/techtips/termios-vmin-vtime.html
	tty_opts.c_cc[VMIN]  = 0;
	tty_opts.c_cc[VTIME] = 0;
	//end3

	foo=tcsetattr(tty,TCSANOW, &tty_opts);
	if(foo<0) return -4;
	
	return 0;
}

int tty_test_connection(int tty)
{
	int foo;
	char buf[4]={'p',0,0,0};
	
	foo=write(tty,buf,1);
	if(foo<0){
		perror("write");
		return foo;
	}
	if(foo==0){
		puts("nothing written");
		return foo;
	}
L0:
	foo=read(tty,buf,2); //mc should return 2 bytes p and \0
	if(foo<0){
		perror("read");
		return foo;
	}
	if(foo<2){
		puts("less then 2 bytes was red");
		return foo;
	}

	buf[foo]='\0';
	printf("ping was: %s\n",buf);
	return foo;
}

int main(int ac,char *av[])
{
	int tty_dev;
	int foo;
	
	tty_dev=0;
	tty_dev = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
	if(tty_dev < 0){
		perror("open");
		return -1;
	}
	puts("open: ok");
	
	foo=tty_set(tty_dev);
	if(foo<0){
		perror("tty_set");
		close(tty_dev);
		return -1;
	}
	puts("tty_set: ok");
	
	
	foo=tty_test_connection(tty_dev);
	if(foo<0){
		perror("tty_test_connection");
		printf("foo: %d\n",foo);
		return -1;
	}
	printf("tty_test_connection: %d characters red\n",foo);
	close(tty_dev);
	return 0;
}
The problem is: when read() (see L0 lebel) is executed it returns either "resource temporarily unavailable" or 0.
* mc is working fine. I tested it with screen(1) and minicom(1)
* if set VTIME or VMIN in not 0 value it behaves the same.
* using fscanf(3) just block the program.
* google does not give sufficient results.
Does anyone know where is the problem?
Thanks in advance.

Last edited by nanoo; 07-09-2009 at 10:11 AM.
 
Old 07-12-2009, 06:59 PM   #2
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
Quote:
Originally Posted by nanoo View Post
The problem is: when read() (see L0 lebel) is executed it returns either "resource temporarily unavailable" or 0.
This is because you have open()ed as a non-blocking file descriptor. I suggest you either open() as blocking or use select()/poll().
Quote:
Originally Posted by nanoo View Post
* using fscanf(3) just block the program.
fscanf() should block until it encounters a newline.
 
Old 07-13-2009, 05:02 AM   #3
nanoo
LQ Newbie
 
Registered: Jul 2009
Posts: 19

Original Poster
Rep: Reputation: 1
Ok. I tried to open it in blocking mode removing NDELAY flag in open() func. But now read() returns 0 a couple of thousands times and then returns what it should. As I understand all of this time buffer was empty (0 means eof as written in man page) and when data arrive it read data.
Am I right?
I think there are only two solutions. Either using sigaction to react on SIGIO or using select/poll as you advice. Do any other ways exist?
Thank for help!

Last edited by nanoo; 07-13-2009 at 05:24 AM.
 
Old 07-13-2009, 05:15 PM   #4
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
Quote:
Originally Posted by nanoo View Post
I tried to open it in blocking mode removing NDELAY flag in open() func.
If you want to make normal non-blocking I/O, you will need to get rid of the VTIME and VMIN stuff.

Unless I misunderstood your motives, it seems as though blocking I/O is sufficient, as non-blocking will some extra code for no real benefit (unless your device is timing-sensitive or something).
 
Old 07-14-2009, 09:53 AM   #5
nanoo
LQ Newbie
 
Registered: Jul 2009
Posts: 19

Original Poster
Rep: Reputation: 1
Ok. Now tty_test_connection looks like that:
Code:
int tty_test_connection(int tty)
{
	int foo;
	char buf[4]={'p',0,0,0};
	
	struct pollfd descriptor;
	memset(&descriptor,0,sizeof(struct pollfd));
	
	foo=write(tty,buf,1);
	if(foo<0){
		perror("write");
		return foo;
	}
	if(foo==0){
		puts("nothing written");
		return foo;
	}

L0:
	descriptor.fd=tty;
	descriptor.events = POLLIN;
	foo=poll(&descriptor,1,2000);
	if(foo<0){
		perror("poll");
		return foo;
	}
	if(foo==0){
		puts("poll timeout");
		goto L0;
	}
	if(descriptor.revents && POLLIN == POLLIN){
		foo=read(tty,buf,4);
		if(foo<0){
			perror("read");
			return foo;
		}
	} else {
		puts("no POLLIN in revents");
		return 0;
	}
	
	buf[foo]='\0';
	printf("ping was: %s\n",buf);
	return foo;
}
I also commented VTIME and VMIN stuff.
It seems it is working know, but program behave a bit strange. If I plug usb cable in, wait when /dev/ttyUSB0 appears an start program I get
[CODE]
./a.out
open: ok
tty_set: ok
poll timeout
poll timeout
.....
[\CODE]
after C-c and restarting program several times it work perfect then.
Can you explain what I did wrong?
Thanks!

Last edited by nanoo; 07-14-2009 at 09:55 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
HOW TO connect HUAWEI ETS1201 FWT modem "ttyUSB0 is missing" saka Linux - Newbie 3 04-27-2009 01:14 PM
SynCE & ppc-6800 (Mogul): I get no /dev/ttyUSB0 & "Hal reports no devices connected" lumix Linux - Hardware 3 07-03-2008 10:03 AM
Cifs "mount error 11 = Resource temporarily unavailable" humbletech99 Linux - Networking 1 09-26-2006 12:04 PM
How do I switch the labels "/dev/sda1" with "/dev/sda3" vonst Linux - General 10 05-27-2006 10:48 PM
"/dev/dsp: Device or resource busy" Cdzin Linux - Hardware 4 02-25-2004 06:39 AM


All times are GMT -5. The time now is 03:24 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration