Russian Qt Forum
Января 16, 2025, 11:09 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Чтение данных с СОМ порта  (Прочитано 8689 раз)
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 (ресурс временно не доступен),  ресурс больше нигде в проге не используется. Как мне быть?  Непонимающий
Записан
Rcus
Гость
« Ответ #1 : Апреля 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.
Записан
soalvi
Гость
« Ответ #2 : Апреля 21, 2010, 07:53 »

То есть как я понял код ошибки 11 говорит, что на момент чтения данные на порт не поступили?
Записан
soalvi
Гость
« Ответ #3 : Апреля 21, 2010, 09:13 »

Использовал функцию select для ожидания данных - данные получаю. Но в полученных данных перед нужной мне частью имеется какой-то мусор.
Вызов функции
Код:
read(fd_ttyS0, NULL, sizerequest);
для очистки буфера от остатков не принятых данных возвращает результат errno=11, что трактую как наличие чистого буфера.
Как избавиться от мусора в приёме данных?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Апреля 21, 2010, 10:58 »

soalvi,

не парьте мозх. Улыбающийся

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

или

2. http://fireforge.net/scm/viewvc.php/?root=qserialdevice
Записан

ArchLinux x86_64 / Win10 64 bit
soalvi
Гость
« Ответ #5 : Мая 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);
Помогите разобраться в чем разница? - Данные из программы терминала передаются, а из моей некорректно!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.043 секунд. Запросов: 23.