Буфер последовательного порта Linux не пуст при открытии устройства

#linux #serial-port #pyserial

#linux #последовательный порт #pyserial

Вопрос:

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

Система настроена на запуск автоматических тестов и сначала выполнит некоторые задачи, которые приводят к выводу большого объема данных с последовательного устройства, пока у меня не открыты порты. Устройство также сбросит себя. Подключены только линии tx / rx. Отсутствует управление потоком.

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

Что могло вызвать это? Как Linux обрабатывает буферизацию последовательного порта, когда устройство закрыто? Если бы я открыл устройство, заставил его отправлять выходные данные, а затем закрыл его без чтения с него, вызвало бы это ту же проблему?

Ответ №1:

Драйвер терминала Linux буферизует ввод, даже если он не открыт. Это может быть полезной функцией, особенно если скорость / четность / и т.д. Установлены соответствующим образом.

Чтобы повторить поведение более слабых операционных систем, считайте все ожидающие ввода данные из порта, как только он будет открыт:

 ...
int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0)
        exit (1);

set_blocking (fd, 0);   // disable reads blocked when no input ready

char buf [10000];
int n;
do {
        n = read (fd, buf, sizeof buf);
} while (n > 0);

set_blocking (fd, 1);  // enable read blocking (if desired)

...  // now there is no pending input



void set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (amp;tty, 0, sizeof tty);
        if (tcgetattr (fd, amp;tty) != 0)
        {
                error ("error %d getting term settings set_blocking", errno);
                return;
        }

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = should_block ? 5 : 0; // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, amp;tty) != 0)
                error ("error setting term %sblocking", should_block ? "" : "no");
}
  

Комментарии:

1. Я думал, что это может быть так. Итак, почему я вижу это поведение только часть времени? Я использую pyserial для тестирования, и прилагаемый miniterm.py скрипт как интерактивный терминал. Проблема не только в одном последовательном порту. Кажется, это чередуется. На все серийные порты будут поступать данные, когда они будут закрыты, но только на одном они будут буферизованы в момент, когда я его открою. Возможно, скорость передачи данных оставлена правильно установленной только на этом устройстве?

2. @djs: Скорость порта — это первое, что приходит мне на ум. Также может быть, что gpsd or logind обращается к закрытым портам в поисках устройства GPS или подключения для входа и изменяет скорость порта предположительно.

3. Ни одна из этих служб не запущена. stty сообщил обо всех портах на 115200 прямо перед тем, как я проверил и обнаружил, что только один из них сохранил буфер. Является ли это правильным инструментом для проверки скорости передачи данных?

4. @djs: stty -F /dev/ttyWhatever это то, что я всегда использовал, и у меня никогда не было проблем.

5. У меня все еще нет хорошего объяснения, почему я обычно не вижу такого поведения на последовательных портах. Я настроил тестовую платформу так, чтобы она очищала буфер при запуске, что решает проблему, если не мое любопытство…