#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
orlogind
обращается к закрытым портам в поисках устройства GPS или подключения для входа и изменяет скорость порта предположительно.3. Ни одна из этих служб не запущена. stty сообщил обо всех портах на 115200 прямо перед тем, как я проверил и обнаружил, что только один из них сохранил буфер. Является ли это правильным инструментом для проверки скорости передачи данных?
4. @djs:
stty -F /dev/ttyWhatever
это то, что я всегда использовал, и у меня никогда не было проблем.5. У меня все еще нет хорошего объяснения, почему я обычно не вижу такого поведения на последовательных портах. Я настроил тестовую платформу так, чтобы она очищала буфер при запуске, что решает проблему, если не мое любопытство…