LINUX.ORG.RU

Почему select() может не видеть данные в порте через 20мс после того как они попали в UART?


0

0

сабж

тоесть скажем осцилографом видим что данные приняты портом. Через 20 ms дёргаем select() и он возвращает что данных в порте нету.

если через 30-мс то видит. Собственно вопрос - где они могут задерживатся. Порты интегрированные в Via-Epia

★★★★★

Настройки порта каковы?

PS Задерживаться? В буфере драйвера (в ядре то есть). Имхо надо в сторону termios'ов смотреть. Там туева хуча настроек.

farisey
()
Ответ на: комментарий от farisey

    cfmakeraw(&ti);
    cfsetispeed(&ti, speed);
    cfsetospeed(&ti, speed);

    //c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
    ti.c_iflag |= IGNBRK;//???возможно имеет смысл оставить этот флаг снятым а вместо него поднять BRKINT???
    ti.c_iflag |= IGNPAR;//Ignore framing errors and parity errors.
    ti.c_iflag &= ~(INPCK | PARMRK);
    ti.c_iflag &= ~(IXOFF | IXON | IXANY);    /* disable start/stop i/o flow control*/

    //c_oflag &= ~OPOST;

    ti.c_cflag &= ~(PARENB | PARODD);  /* no parity */
    ti.c_cflag &= ~CSTOPB;             /* 1 stop bit */
    ti.c_cflag &= ~CRTSCTS;            /* no i/o rts/cts flow control */
    ti.c_cflag |= CLOCAL;
    ti.c_cflag |= HUPCL;
    ti.c_cflag |= CREAD;

    //c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
    //Disable  flushing  the  input and output queues when generating the SIGINT, SIGQUIT and SIGSUSP signals. 
    //ti.c_lflag &= ~(NOFLSH);//???возможно потребуется установить/снять???

    ti.c_cc[VMIN] = 0;
    ti.c_cc[VTIME] = 0;

    if (tcsetattr(port->fd, TCSANOW, &ti) < 0)
    {
        syslog(LOG_ERR,"%s(%s):error setting terminal line modes: %m", __func__,  port->name);
        return false;
    }

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

Вроде красиво всё... но 30ms явно много...

Для очистки совести ещё раз глянул мануал по термиосу и свои прожекты с компортом. Блин... всё должно быть ровно. Не знаю, сорри:(((

farisey
()

а этот контролер имеет какого размера буфер?

если буфер есть и он включен, то возможна задержка,
вызваная тем, что прерывание генериться не на каждый байт,
а на несколько.

fghj ★★★★★
()
Ответ на: комментарий от fghj

вс'равно слишком много

На заполнение буффера требуется около милисекунды

uart - 16650A

cvv ★★★★★
() автор топика

Попробуй влепить printk в обработчик прерывания порта, чтобы хоть узнать - железо виновато или ядро.

tailgunner ★★★★★
()
Ответ на: комментарий от cvv

Внутренний буфер ком-порта может быть 1кб - и некоторые слишком умные порты игнорировали настройку прерываний по приходу каждого байта. Незабудь еще возможную задержку от планировщика процессов размером до 10 мсек. Также нужно проверить настройку винта - может стоять отключение всех прерываний при обращении к диску (через hdparm -u). Еще ускорить реакцию помогает опция setserial /dev/ttyS0 low_latency Если-же нужно время реакции менее 10 мсек - то пользовательский процесс нужно переводить на повышенный приоритет через setpriority() или даже через sched_setscheduler( SCHED_FIFO ) или и вовсе использовать реал-тайм Linux

anonymous
()

Читай Роберта Лава, разработка ядра Линукс. Правда там для 2.6 в общем есть top half, а есть bщttom half.

top half - выполняется непосредственно для обработки прерывания bottom half - несколько позже

yantux
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.