alex_x80 Опубликовано 26 июня, 2009 Жалоба Поделиться Опубликовано 26 июня, 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 мс! Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
sv_lary Опубликовано 2 июля, 2009 Жалоба Поделиться Опубликовано 2 июля, 2009 Здравствуйте ! Знаете, этот код оставляет странное впечатление... Типа, что он перенесен по копи/паст из ... Даже не знаю - откуда ! В частности, используются BSD и устаревшие опции... Может быть оставить все настройки СОМ-порта (кроме скорости) по умолчанию ? А самое главное замечание, Вы используете RAW режим работы с СОМ-портом : tinfo.c_lflag&=~(ICANON Но не уточняете параметры работы в НЕканоническом режиме. Т.е., раз Вы задаете НЕканонический режим, то должны и задать параметры : buf.c_cc[VMIN] = <<Минимальное количество байт>>; buf.c_cc[VTIME] = <<Время тайм-аута>>; Попробуйте поварьировать эти параметры, может быть - в них дело ? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Edward_Em Опубликовано 2 июля, 2009 Жалоба Поделиться Опубликовано 2 июля, 2009 ioctl(comfd,TCGETA,&oldtty); // Узнаем текущие параметры порта tty = oldtty; tty.c_lflag = 0; tty.c_iflag = BRKINT; tty.c_oflag = 0; tty.c_cflag = B9600|CS8|CREAD|CLOCAL|PARENB; tty.c_cflag &= ~PARODD; // это, смотря какую вам надо четность tty.c_cc[VMIN] = 0; tty.c_cc[VTIME] = 1; ioctl(comfd,TCSETA,&tty); Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
alex_x80 Опубликовано 2 июля, 2009 Автор Жалоба Поделиться Опубликовано 2 июля, 2009 Пробовали, не помогает. Единственный способ, которым удалось быстро считывать данные - это прямой доступ к портам (inb\outb). Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.