Russian Qt Forum

Программирование => С/C++ => Тема начата: soalvi от Апреля 20, 2010, 10:54



Название: Чтение данных с СОМ порта
Отправлено: soalvi от Апреля 20, 2010, 10:54
Здравствуйте.
Написал прогу которая выдаёт данные в СОМ (ttyS1) и читает из него. Выдача работает нормально - приёмник данные получает, а вот чтение почему-то не идёт  :( , фрагмент моего кода:
Код:
fd_ttyS0 = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(fd_ttyS0, &options);
cfsetispeed(&options, B19200);
options.c_cflag |= (CLOCAL | CREAD | PARENB);
tcsetattr(fd_ttyS0, TCSAFLUSH, &options);
fcntl(fd_ttyS0, F_SETFL, FNDELAY);
...
read(fd_ttyS0, &buff[0], sizerequest);
Функция read возвращает errno=11 (ресурс временно не доступен),  ресурс больше нигде в проге не используется. Как мне быть?  ???


Название: Re: Чтение данных с СОМ порта
Отправлено: Rcus от Апреля 20, 2010, 11:36
FNDELAY это флаг O_NONBLOCK, который переводит дескриптор в неблокирующий режим. Код ошибки 11 обычно это EAGAIN. см. man 3 read
Цитировать
When attempting to read a file (other than a pipe or FIFO) that supports non-blocking reads and has no data currently available:

        * If O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN].

        * If O_NONBLOCK is clear, read() shall block the calling thread until some data becomes available.

        * The use of the O_NONBLOCK flag has no effect if there is some data available.


Название: Re: Чтение данных с СОМ порта
Отправлено: soalvi от Апреля 21, 2010, 07:53
То есть как я понял код ошибки 11 говорит, что на момент чтения данные на порт не поступили?


Название: Re: Чтение данных с СОМ порта
Отправлено: soalvi от Апреля 21, 2010, 09:13
Использовал функцию select для ожидания данных - данные получаю. Но в полученных данных перед нужной мне частью имеется какой-то мусор.
Вызов функции
Код:
read(fd_ttyS0, NULL, sizerequest);
для очистки буфера от остатков не принятых данных возвращает результат errno=11, что трактую как наличие чистого буфера.
Как избавиться от мусора в приёме данных?


Название: Re: Чтение данных с СОМ порта
Отправлено: kuzulis от Апреля 21, 2010, 10:58
soalvi,

не парьте мозх. :)

Посмотрите, наконец, как это сделано в:
1. http://code.google.com/p/qextserialport/

или

2. http://fireforge.net/scm/viewvc.php/?root=qserialdevice


Название: Re: Чтение данных с СОМ порта
Отправлено: soalvi от Мая 04, 2010, 15:58
Добился следующего результата: С другого ПК из под Windows используя программу терминал передаю в Linux данные - данные передаются корректно. Но когда начинаю передачу из своей программы (из под Windows) то данные принимаются кусками - из посылки выборочно принимается 2-4 байта.
Текст программы передатчика (из под Windows, Builder):
Код:
  port = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0,
                    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  SetupComm (port, 2048, 2048);
  GetCommState (port, &dcb);
    dcb.ByteSize = 8;
    dcb.Parity = EVENPARITY;
    dcb.BaudRate = CBR_19200;
    dcb.StopBits = ONESTOPBIT;
  SetCommState (port, &dcb);
  GetCommTimeouts (port, &time);
    time.ReadTotalTimeoutConstant = 0;
  SetCommTimeouts (port, &time);

  while (true)
  {  WriteFile(port, &data[0], 8, &RetDat, NULL);  }
Вот как теперь выглядит мой текст под Linux:
Код:
    fd_ttyS0 = open("/dev/ttyS0", O_RDWR| O_NOCTTY | O_NDELAY);
    tcgetattr(fd_ttyS0, &options);
    cfsetispeed(&options, B19200);
    cfsetospeed(&options, B19200);
    options.c_cflag |= (CLOCAL | CREAD | CS8 | PARENB);
    options.c_lflag &= ~(ICANON | ECHO | ECHOE);
    options.c_oflag &= ~(OPOST);
    options.c_iflag &= ~(INLCR | IGNCR | ICRNL);
    tcsetattr(fd_ttyS0, TCSAFLUSH, &options);
    fcntl(fd_ttyS0, F_SETFL, FNDELAY);
...
    timeout.tv_sec  = 3;
    timeout.tv_usec = 100;
    memset(&buff[0], 0, SizeBuf);
    FD_SET(fd_ttyS0, &readfs);
    select(fd_ttyS0, &readfs, NULL, NULL, &timeout);
    read(fd_ttyS0, &buff[0], SizeBuf);
Помогите разобраться в чем разница? - Данные из программы терминала передаются, а из моей некорректно!