Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

задержка при чтении COM порта под Linux

50K
26 июня 2009 года
alex_x80
2 / / 26.06.2009
Добрый день! Есть девайс,подключенный к 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 мс!
9.3K
26 июня 2009 года
iridum
175 / / 26.08.2007
Наверное лучше всего для таких коротких задержек использовать внешкий девайс, который и будет общаться с устройством. Я слышал про дополнения для LINUX, при которых достигаеться работа в режиме реального времени

http://www.citforum.ru/operating_systems/articles/linuxrt.shtml
50K
29 июня 2009 года
alex_x80
2 / / 26.06.2009
удалось ускориться только через прямое чтение портов, но иногда некоторые полученные значения теряются....
7.7K
30 июля 2009 года
Elder386
38 / / 06.04.2005
Цитата: alex_x80
удалось ускориться только через прямое чтение портов, но иногда некоторые полученные значения теряются....



а можно подробней как это прямое? как модуль ядра?

у меня была та же проблема. и еще вопрос кроме задержки вдобавок не получалось прочитать состояние бита четности, только менять и то как-то странно работало. там девайсина не ловила пакет данных без установки этого бита для первого байта. а сами девайсы слали ответы наоборот - завершалось помеченым битом.

как писать напрямик в порт и как читать бит четности?

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог