LINUX.ORG.RU

Работа с COM-портом : resourse temporarily unavailable


0

0

Пишу программу под Debian, для взаимодействия с устройством через СОМ-порт. Порт нормально открывается, я его конфиурирую, но при попытке чтония получаю -1. В errno - "resourse temporarily unavailable"

fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
printf("Дескриптор порта: %d \n ", fd);

tcgetattr(fd, &options);

cfsetispeed(&options, B4800);
cfsetospeed(&options, B4800);

options.c_cflag |= CS8 | CLOCAL | CREAD;
tcsetattr(fd, TCSANOW, &options);

int buf[5];
int flg;

flg = read(fd, buf,1);

Почему ресурс может быть недоступен?

кто-то захватил лизу.

man fcntl

cvv ★★★★★
()

Вроде бы, "resourse temporarily unavailable" это было EAGAIN. А он вылазит в случае, когда нет данных, а устройство открыто в режиме O_NONBLOCK == O_NDELAY. То есть у вас просто не успевают придти данные в порт.

P.S. Лучше приводите код ошибки (значение errno), чем то, что дает strerror().

mky ★★★★★
()

А если

system("stty < /dev/ttyS0 <настройки порта>")

и потом fopen("/dev/ttyS0", ...)

?

marsijanin ★★
()
Ответ на: комментарий от mky

Да кажись ты прав. то я наверное с утра не успел проснутся

cvv ★★★★★
()
Ответ на: комментарий от mky

errno = 11

Пробовал fcntl(fd, F_SETFL, FNDELAY) перед read - эффект тот же. с fcntl(fd, F_SETFL, 0) прога засыпает.

Насколько я понимаю, при fcntl(fd, F_SETFL, FNDELAY) read должен возвращать 0, если данных просто нет?

Lohmatii
() автор топика
Ответ на: комментарий от cvv

>я бы не стал применять эту штучку к COM-портам а почему? Собственно, такую рекомендацию я нашел в Serial Programming Guide for POSIX Operating Systems

Lohmatii
() автор топика
Ответ на: комментарий от Lohmatii

Да, есть там такая рекомендация. Но, в старом Serial Port Programming How-To советовали использовать seletc() перед чтением. В моей версии glibc объявлено "# define FNDELAY O_NDELAY".

ИМХО, используйте select() на порту открытом с O_NDELAY и считайте, что если read() вернул -1, а errno == EAGAIN, то это нормально.

mky ★★★★★
()
Ответ на: комментарий от Lohmatii

во первых потому что эта настройка конфликтует с настройками сделанными tcsetattr и как следствие проще запутатся и сложнее сделать разбор полёта.

во вторых режим блокирования я предпочитаю выставлять при открытиии порта и больше не изменять.

cvv ★★★★★
()
Ответ на: комментарий от cvv

Большое спасибо, с этим я кажется разобрался.

Такой вопрос. Мне, по все видимости, нужно использовать запросы
TIOCMGET, TIOCM_RTS, TIOCM_DTR, TIOCMSET системного вызова ioctl.
Проблема в том, что gcc их не находит, хотя unistd.h и termios.h
подключены. С чем это может быть связано?
POSIX-функций для этих вызовов, кажется, нет?

Lohmatii
() автор топика
Ответ на: комментарий от Lohmatii

>хотя unistd.h и termios.h подключены.

этого не достаточно. как минимум ещё нужны <sys/ioctl.h>

если не хватит - пройдись поиском по /usr/include/

>POSIX-функций для этих вызовов, кажется, нет?

да не существует

cvv ★★★★★
()
Ответ на: комментарий от cvv

которую ночь тружусь - прибор все не отвечает. Есть программа под Винду, которая нормально с ним работает. Просмотр ее работы портмоном выдал ряд запросов, которые мне не совсем понятны. Вот что творится под виндой:

IOCTL_SERIAL_SET_WAIT_MASK Serial0 Mask: RXCHAR RXFLAG TXEMPTY CTS DSR RLSD BRK ERR RING IOCTL_SERIAL_SET_TIMEOUTS Serial0 RI:-1 RM:0 RC:0 WM:0 WC:0 IOCTL_SERIAL_GET_BAUD_RATE Serial0 IOCTL_SERIAL_GET_LINE_CONTROL Serial0 IOCTL_SERIAL_GET_CHARS Serial0 IOCTL_SERIAL_GET_HANDFLOW Serial0 IOCTL_SERIAL_GET_BAUD_RATE Serial0 IOCTL_SERIAL_GET_LINE_CONTROL Serial0 IOCTL_SERIAL_GET_CHARS Serial0 IOCTL_SERIAL_GET_HANDFLOW Serial0 IOCTL_SERIAL_SET_BAUD_RATE Serial0 Rate: 4800 IOCTL_SERIAL_SET_RTS Serial0 IOCTL_SERIAL_SET_DTR Serial0 IOCTL_SERIAL_SET_LINE_CONTROL Serial0 StopBits: 1 Parity: NONE WordLength: 8 IOCTL_SERIAL_SET_CHAR Serial0 EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13 IOCTL_SERIAL_SET_HANDFLOW Serial0 Shake:1 Replace:40 XonLimit:1024 XoffLimit:1024 IOCTL_SERIAL_SET_QUEUE_SIZE Serial0 InSize: 4096 OutSize: 2048 IOCTL_SERIAL_SET_RTS Serial0 IOCTL_SERIAL_CLR_RTS Serial0 IRP_MJ_WRITE Serial0 Length 10: 7E 02 01 00 3B 3D 01 12 B4 0D IOCTL_SERIAL_WAIT_ON_MASK Serial0 IOCTL_SERIAL_GET_COMMSTATUS Serial0 IOCTL_SERIAL_SET_RTS Serial0 IOCTL_SERIAL_WAIT_ON_MASK Serial0 IOCTL_SERIAL_GET_COMMSTATUS Serial0 IRP_MJ_READ Serial0 Length 7 SUCCESS Length 7: 6F 59 7F 63 67 EB EF

Вот, что делаю я: main() { int fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { return 0; }

struct termios term; tcgetattr(fd, &term);

cfsetispeed(&term, B4800); cfsetospeed(&term, B4800);

term.c_cflag &= ~CSIZE; term.c_cflag |= CS8; term.c_cflag |= CLOCAL | CREAD;

term.c_cc[VEOF] = 0;

if (tcsetattr(fd, TCSANOW, &term)<0) return 0;

unsigned char buf[10] ={0x7E, 0x02, 0x01, 0x00, 0x3B, 0x3D, 0x01, 0x12, 0xB4, 0x0D};

int n;

n = write(fd, buf, 10); int flg;

flg = read(fd, buf,1); while(flg == -1) { usleep(10000); flg = read(fd, buf,1); } из цикла программа так и не выходит. Постоянно EAGAIN (Resource temporarily unavailable). Подскажите пожалуйста, что такое IOCTL_SERIAL_SET_WAIT_MASK Serial0 Mask: RXCHAR RXFLAG TXEMPTY CTS DSR RLSD BRK ERR RING IOCTL_SERIAL_SET_TIMEOUTS Serial0 RI:-1 RM:0 RC:0 WM:0 WC:0 IOCTL_SERIAL_SET_HANDFLOW Serial0 Shake:1 Replace:40 XonLimit:1024 XoffLimit:1024 и чему соответтвуют символы ERR BRK EVT XON XOFF в Linux?

Lohmatii
() автор топика
Ответ на: комментарий от Lohmatii

формат сбился. Вот в читабельном виде:
которую ночь тружусь - прибор все не отвечает. Есть программа под Винду, которая нормально с ним работает.
Просмотр ее работы портмоном выдал ряд запросов, которые мне не совсем понятны. Вот что творится под виндой: 

IOCTL_SERIAL_SET_WAIT_MASK     Serial0  Mask: RXCHAR RXFLAG TXEMPTY CTS DSR RLSD BRK ERR RING 
IOCTL_SERIAL_SET_TIMEOUTS      Serial0  RI:-1 RM:0 RC:0 WM:0 WC:0
IOCTL_SERIAL_GET_BAUD_RATE     Serial0  
IOCTL_SERIAL_GET_LINE_CONTROL  Serial0  
IOCTL_SERIAL_GET_CHARS         Serial0  
IOCTL_SERIAL_GET_HANDFLOW      Serial0  
IOCTL_SERIAL_GET_BAUD_RATE     Serial0  
IOCTL_SERIAL_GET_LINE_CONTROL  Serial0  
IOCTL_SERIAL_GET_CHARS         Serial0  
IOCTL_SERIAL_GET_HANDFLOW      Serial0  
IOCTL_SERIAL_SET_BAUD_RATE     Serial0  Rate: 4800
IOCTL_SERIAL_SET_RTS           Serial0  
IOCTL_SERIAL_SET_DTR           Serial0  
IOCTL_SERIAL_SET_LINE_CONTROL  Serial0  StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR          Serial0  EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW      Serial0  Shake:1 Replace:40 XonLimit:1024 XoffLimit:1024
IOCTL_SERIAL_SET_QUEUE_SIZE    Serial0  InSize: 4096 OutSize: 2048
IOCTL_SERIAL_SET_RTS           Serial0  
IOCTL_SERIAL_CLR_RTS           Serial0  
IRP_MJ_WRITE                   Serial0  Length 10: 7E 02 01 00 3B 3D 01 12 B4 0D 
IOCTL_SERIAL_WAIT_ON_MASK      Serial0  
IOCTL_SERIAL_GET_COMMSTATUS    Serial0  
IOCTL_SERIAL_SET_RTS           Serial0  
IOCTL_SERIAL_WAIT_ON_MASK      Serial0  
IOCTL_SERIAL_GET_COMMSTATUS    Serial0  
IRP_MJ_READ                    Serial0  Length 7
SUCCESS  Length 7: 6F 59 7F 63 67 EB EF 

Вот, что делаю я:
main()
{
	int fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
	if (fd < 0)
	{		
		return 0;
	}

	struct termios term;
	
	tcgetattr(fd, &term);

	cfsetispeed(&term, B4800);
	cfsetospeed(&term, B4800);

	term.c_cflag &= ~CSIZE;
	term.c_cflag |=  CS8;
	term.c_cflag |=  CLOCAL | CREAD;

	term.c_cc[VEOF] = 0;

	if (tcsetattr(fd, TCSANOW, &term)<0)
		return 0;

	unsigned char buf[10] ={0x7E, 0x02, 0x01, 0x00, 0x3B, 0x3D, 0x01, 0x12, 0xB4, 0x0D};

	int n;

	n = write(fd, buf, 10);
	int flg;

	flg = read(fd, buf,1);
	while(flg == -1)
	{
		usleep(10000);
		flg = read(fd, buf,1);
	}
из цикла программа так и не выходит. Постоянно EAGAIN (Resource temporarily unavailable).
Подскажите пожалуйста, что такое 
IOCTL_SERIAL_SET_WAIT_MASK     Serial0  Mask: RXCHAR RXFLAG TXEMPTY CTS DSR RLSD BRK ERR RING 
IOCTL_SERIAL_SET_TIMEOUTS      Serial0  RI:-1 RM:0 RC:0 WM:0 WC:0
IOCTL_SERIAL_SET_HANDFLOW      Serial0  Shake:1 Replace:40 XonLimit:1024 XoffLimit:1024
и чему соответтвуют символы ERR BRK EVT XON XOFF в Linux?

Lohmatii
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.