The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"задержка при чтении COM-порта под Linux"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"задержка при чтении COM-порта под Linux"  +/
Сообщение от alex_x80 (ok) on 26-Июн-09, 10:56 
Добрый день! Есть девайс,подключенный к COM-порту. Протокол обмена таков: посылаем 2 байта вопроса и читаем 3 байта ответа. Осциллографом четко видны посылки к устройству и практически сразу же ответ, все вместе занимает приблизительно 0,5 мс, однако функция чтения read возвращает значение только через 10 мс! Подскажите, как ускорить этот процесс до 1мс?
Пример программы:

char dev[] = "/dev/ttyS0";
port=open(dev,O_RDWR | O_NDELAY | O_NOCTTY);
if (port==-1) {
    printf("err: failed to open ""%s""!",dev);
    return 1;
}

  //если поставить этот кусок, то задержка уменьшается до 4 мс, но этого мало
  struct serial_struct ser;
  ioctl(port, TIOCGSERIAL, &ser);
  ser.flags |= ASYNC_LOW_LATENCY;
  ioctl(port, TIOCSSERIAL, &ser);
  
  //настройки порта таковы
  termios tinfo;
  fcntl(port,F_SETFL, 0); //ждать запрошенных данных
  tcgetattr(port,&tinfo);

  tinfo.c_cflag&=~(CSIZE | CRTSCTS | CSTOPB);
  tinfo.c_cflag|=(CLOCAL | CREAD | CS8 | PARENB | CBAUD);
  tinfo.c_iflag&=~(ISTRIP | IXON | IXOFF | IXANY | IGNBRK | BRKINT | PARMRK | INLCR | IGNCR | ICRNL);
  tinfo.c_iflag|=(INPCK);
  tinfo.c_oflag&=~OPOST;
  tinfo.c_lflag&=~(ICANON | ECHO | ECHONL | ECHOE | ISIG | IEXTEN);

  cfsetospeed(&tinfo,B115200);
  cfsetispeed(&tinfo,B115200);
  tcflush(port,TCIFLUSH);
  tcsetattr(port,TCSANOW,&tinfo);

//собственно главный цикл, который выполняется 10 мс
char bufO[2]={10,10};
char buf[20];
while(1)
{ write(port,bufO,2);
  read(port,buf,3);
}

Если поставить чтение без задержки fcntl(port,F_SETFL, FNDELAY), а использовать другие механизмы (через select, либо читать в цикле пока не наберется 3 байта) - результат один и тот же: цикл выполняется недопустимо медленно. Хотя под Windows XP аналогичная программа опрашивает данное устройство окло 1 мс!

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "задержка при чтении COM-порта под Linux"  +/
Сообщение от hold_fast_ (ok) on 26-Июн-09, 11:43 
1А. Попробуйте использовать флаг O_NONBLOCK. Маловероятно, но может будет разница.
port=open(dev,O_RDWR | O_NOCTTY | O_NONBLOCK);

1Б. Я бы еще добавил следующее:

tinfo.c_cc[VMIN]=1;
tinfo.c_cc[VTIME]=0;

2. Попробуйте использовать чтение/запись в разных потоках.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "задержка при чтении COM-порта под Linux"  +/
Сообщение от alex_x80 (??) on 26-Июн-09, 11:56 
>1А. Попробуйте использовать флаг O_NONBLOCK. Маловероятно, но может будет разница.
>port=open(dev,O_RDWR | O_NOCTTY | O_NONBLOCK);
>
>1Б. Я бы еще добавил следующее:
>
>tinfo.c_cc[VMIN]=1;
>tinfo.c_cc[VTIME]=0;
>
>2. Попробуйте использовать чтение/запись в разных потоках.

Пробовали с флагом O_NONBLOCK, варьировали параметры tinfo.c_cc, меняли размер буфера xmit_fifo_size - ничего не влияет. Единственное, что частично помогло, это на одном из имортных форумом кому-то в такой же ситуации посоветовали установить флаг ASYNCH_LOW_LATENCY. Есть подозрение, что такова особенность ОС Linux, и средствами стандартного драйвера более высокого быстродействия добиться невозможно. Если кто-то точно знает что это так - пожалуйста, отпишитесь.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру