Отправляет email-рассылки с помощью сервиса Sendsay

Не получается открыть COM порт

Привет !

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

Для экспериментов я использую свой модем (тк мультиметр не мой).
Так вот, при открытии файла порта, происходит зависание программы.
При этом светодиод модема загорается, те в порт я попадаю.
Работаю под рутом, с правами игрался. Не пойму в чём затык.
Модем работает нормально.

Пишу на Паскале, но и на сишном примере
из Serial-Programming-HOWTO то же самое.

"Прямая" попытка:

var
port : Text;

begin

Assign(port, '/dev/ttyS1');

FileMode := 2;

ReWrite(port); // здесь происходит зависание

WriteLn('!');

WriteLn(port, 'ATDP100');

ReadLn;

Close(port);

Через специальную библиотеку:

{$MODE DELPHI}

Program testser;

uses
synaser{, sysutils};

var
ser:TBlockSerial;
begin
ser:=TBlockserial.Create;
try
ser.RaiseExcept:=True;
ser.Connect('/dev/ttyS1'); // здесь происходит зависание
WriteLn('!');
ser.Config(9600,8,'N',0,false,false);
writeln (ser.ATCommand('ATDP100'));
finally
ser.Free;
end;
end.

Пример на Си из Serial-Programming-HOWTO :

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

/* установки бодрейта определены в <asm/termbits.h>, который подключается файлом
<termios.h> */
#define BAUDRATE B38400

/* измените это на правильное устройство в вашем случае */
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX-совместимый код */
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

main()
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];

/*
Открываем модемное устройство для чтения и записи и не как терминал
потому что нам не нужно завершение в случае появления в линии CTRL-C
*/
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); // здесь происходит зависание
if (fd <0) {perror(MODEMDEVICE); exit(-1); }

tcgetattr(fd,&oldtio); /* сохраняем текущие настройки порта */
bzero(&newtio, sizeof(newtio)); /* очищаем структуру под новые настройки */

/*
BAUDRATE: Установка кол-ва бод в секунду. Также можно воспользоваться
cfsetispeed и cfsetospeed.
CRTSCTS : аппаратное управление исходящим потоком (используется только
если кабель содержит все необходимые линии. Смотрите раздел 7
Serial-HOWTO)
CS8 : 8n1 (8 бит, без контроля четности, 1 стопбит)
CLOCAL : локальное соединение, без управления модемом
CREAD : разрешаем получать символы
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

/*
IGNPAR : игнорируем байты с ошибками четности
ICRNL : отображаем CR на NL (иначе появление CR на другом компьютере не
завершит ввод)
в остальном оставляем устройство ненастроенным (raw, без других обработок
ввода)
*/
newtio.c_iflag = IGNPAR | ICRNL;

/* Ненастроенный (raw, как есть) вывод */
newtio.c_oflag = 0;

/*
ICANON : включаем режим канонического ввода
отключаем любую эхо-функциональность и не посылаем
сигналов вызвавшей программе
*/
newtio.c_lflag = ICANON;

/*
инициализируем все управляющие символы
значения по умолчанию можно найти в /usr/include/termios.h и они
продублированы в комментариях, но здесь они не необходимы
*/
newtio.c_cc[VINTR] = 0; /* Ctrl-c */
newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
newtio.c_cc[VERASE] = 0; /* del */
newtio.c_cc[VKILL] = 0; /* @ */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VTIME] = 0; /* междусимвольный таймер выключен */
newtio.c_cc[VMIN] = 1; /* блокировать read до появления 1 символа */
newtio.c_cc[VSWTC] = 0; /* '\0' */
newtio.c_cc[VSTART] = 0; /* Ctrl-q */
newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
newtio.c_cc[VEOL] = 0; /* '\0' */
newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */
newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */
newtio.c_cc[VWERASE] = 0; /* Ctrl-w */
newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */
newtio.c_cc[VEOL2] = 0; /* '\0' */

/* сбрасываем модемную линию и активируем настройки порта */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);

/*
настройка терминала выполнена, теперь обрабатываем ввод
в этом примере появление 'z' в начале строки завершит программу
*/

while (STOP==FALSE) { /* повторять до выставления условия останова */
/* read блокирует выполнение программы до появления символа конца строки
даже если получено больше 255 символов. Если количество считанных
символов меньше количества поступивших симоволов, то последующие
вызовы read вернут оставшиеся символы. res будет содержать
количество реально считанных символов */
res = read(fd,buf,255);
buf[res]=0; /* устанавливаем конец строки чтобы вызвать printf */
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=TRUE;
}
/* восстанавливаем исходные настройки порта */
tcsetattr(fd,TCSANOW,&oldtio);
}

Извиняюсь за размер письма.

Спасибо,
Александр

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32661; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693779

Ответить   Fri, 28 Sep 2007 18:30:42 +0400 (#693779)

 

Ответы:

В сообщении от 28 сентября 2007 17:30 Alexander написал(a):

А затык возникает только в самописных программах или так же если
попытаться залезть на него через minicom или что-нибудь ему подобное?

Так же возможно что какой-то процесс на нем уже висит. (Что насчет ps
ax | grep ttyS1 ?)

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32662; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693780

Ответить   Fri, 28 Sep 2007 17:35:09 +0300 (#693780)

 

После запуска minicom (он работает нормально) мои
программы тоже стали открывать порт, но команды модему
всё равно не посылают.

В "прямой" WriteLn вообще проскакивает без эффекта,
а программа, использующая библиотеку отваливается с ошибкой,
пишет: ESynaSerError : Communication error 9997: Timeout during operation

Вот ведь блин.

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32663; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693797

Ответить   Fri, 28 Sep 2007 19:26:08 +0400 (#693797)

 

Разобрался с таймаутом. Выключил поднятие исключений (а то библиотека спешит
с выводами о таймауте) и
вставил readln; чтобы успел набрать номер. С этим всё, начинаю изучение функций
библиотеки.

Но что сделал миником я так и не понял. Спасибо !

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32665; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693857

Ответить   Fri, 28 Sep 2007 22:26:52 +0400 (#693857)

 

В сообщении от 28 сентября 2007 21:26 Alexander написал(a):

можно посмотреть сравнив вывод stty -aF /dev/ttyS1 до и после миникома.
Только чтобы такое сделать устройство нужно хоть как-то открыть для
начала.

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32666; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693862

Ответить   Fri, 28 Sep 2007 21:48:39 +0300 (#693862)

 

28 сентября 2007, Amper написал:

Не винды - это как раз не фатально. Другое дело что процессы друг у друга
вводимые данные таскать будут. Но это проявится позже, да и заметно это.

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32668; Возраст листа: 1527; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693883

Ответить   Сергей Хватов Fri, 28 Sep 2007 22:27:23 +0400 (#693883)

 

В сообщении от 28 сентября 2007 17:30 Alexander написал(a):

а если добавить O_NONBLOCK ?

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32664; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693816

Ответить   Fri, 28 Sep 2007 19:00:39 +0300 (#693816)

 

28 сентября 2007, Alexander написал:

Serial Programming Guide for POSIX Operating Systems
(http://www.easysw.com/~mike/serial/serial.html) - этот? Там всё описано
адекватно.

[...]

Здесь действительно можно зависнуть если изначально нет CLOCAL и нет сигнала
CD. Поэтому нужно открывать с флагом O_NDELAY а потом его убирать через
fcntl(). В linux в отличие от sysv нет никаких умолчаний для параметров tty,
и после последнего закрытия они также не сбрасываются.

Опять - так поступать крайне рисковано. В struct termios могут быть
неописанные, но существенные поля (и как раз в sysv они были), поэтому её
нельзя формировать с ноля - надо считывать существующую а потом её изменять.

Дальше разбирать не стал.

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32667; Возраст листа: 1527; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693882

Ответить   Сергей Хватов Fri, 28 Sep 2007 22:24:29 +0400 (#693882)