alex_x80 Posted June 26, 2009 Report Share Posted June 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 мс! Quote Link to comment Share on other sites More sharing options...
sv_lary Posted July 2, 2009 Report Share Posted July 2, 2009 Здравствуйте ! Знаете, этот код оставляет странное впечатление... Типа, что он перенесен по копи/паст из ... Даже не знаю - откуда ! В частности, используются BSD и устаревшие опции... Может быть оставить все настройки СОМ-порта (кроме скорости) по умолчанию ? А самое главное замечание, Вы используете RAW режим работы с СОМ-портом : tinfo.c_lflag&=~(ICANON Но не уточняете параметры работы в НЕканоническом режиме. Т.е., раз Вы задаете НЕканонический режим, то должны и задать параметры : buf.c_cc[VMIN] = <<Минимальное количество байт>>; buf.c_cc[VTIME] = <<Время тайм-аута>>; Попробуйте поварьировать эти параметры, может быть - в них дело ? Quote Link to comment Share on other sites More sharing options...
Edward_Em Posted July 2, 2009 Report Share Posted July 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); Quote Link to comment Share on other sites More sharing options...
alex_x80 Posted July 2, 2009 Author Report Share Posted July 2, 2009 Пробовали, не помогает. Единственный способ, которым удалось быстро считывать данные - это прямой доступ к портам (inb\outb). Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.