Корректная последовательность инициализации для последовательного порта Linux

Я записал приложение, которое должно использовать последовательные порты на Linux, особенно ttyUSB. Чтение и запись операций выполняются со стандартным выбором () / чтение () цикл и запись (), и нет, вероятно, ничего неправильно в них, но код инициализации (или отсутствие некоторой части его) повреждает что-то в tty подсистеме.Вот:


  vuxboot(string filename, unsigned baud = B115200) : _debug(false) {
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY);
    if(_fd < 0) throw new io_error("cannot open port");

    // Serial initialization was written with FTDI USB-to-serial converters
    // in mind. Anyway, who wants to use non-8n1 protocol?

    tcgetattr(_fd, &_termios);

    termios tio = {0};
    tio.c_iflag = IGNPAR;
    tio.c_oflag = 0;
    tio.c_cflag = baud | CLOCAL | CREAD | CS8;
    tio.c_lflag = 0;

    tcflush(_fd, TCIFLUSH);
    tcsetattr(_fd, TCSANOW, &tio);
  }

Другой tcsetattr(_fd, TCSANOW, &_termios) находится в деструкторе, но это не важно.

С или без этой termios инициализации, странные вещи происходят в системе после выходов приложения. Иногда плоскость cat (или hd) выходы, сразу печатающие ничто или тот же материал каждый раз, иногда, это ожидает и не отображает любые из данных, которые, конечно, отправляются на порт; и close() (read() также, но не каждый раз), испускает странное WARNING к dmesg, относящемуся к usb-serial.c.

Я проверил аппаратные средства и десятки встроенного микропрограммного обеспечения времен (даже на различных машинах), и я уверен, что они работают, как предназначено; кроме того, я разделил встроенное микропрограммное обеспечение, чтобы просто распечатать то же сообщение много раз.

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

6
задан whitequark 6 June 2010 в 13:21
поделиться

4 ответа

Кстати, на самом деле, ваша проверка ошибок на open не совсем верна - условия ошибки сигнализируются возвращаемым значением -1. (0 - вполне допустимый fd, обычно связанный со стандартным вводом.)

0
ответ дан 17 December 2019 в 18:10
поделиться

Вы можете попробовать:

  vuxboot(string filename, unsigned baud = B115200) : _debug(false) {
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY);
    if(_fd < 0) throw new io_error("cannot open port");

    // Serial initialization was written with FTDI USB-to-serial converters
    // in mind. Anyway, who wants to use non-8n1 protocol?

    tcgetattr(_fd, &_termios);

-   termios tio;
+   termios tio;
+   memcpy(&tio, &_termios, sizeof(struct termios)); 

    tio.c_iflag = IGNPAR;
    tio.c_oflag = 0;
    tio.c_cflag = baud | CLOCAL | CREAD | CS8;
    tio.c_lflag = 0;

    tcflush(_fd, TCIFLUSH);
    tcsetattr(_fd, TCSANOW, &tio);
}

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

0
ответ дан 17 December 2019 в 18:10
поделиться

Нажатие на строку WARN_ON может означать, что вы столкнулись с ошибкой ядра. Я знаю, что в последнее время было проделано много работы по улучшению драйвера последовательного порта USB; Я предлагаю попробовать новое ядро ​​и / или спросить в (скрытом) списке рассылки.

2
ответ дан 17 December 2019 в 18:10
поделиться

Я не уверен, что не так с вашим фрагментом кода, но это может пригодиться, если вы его еще не видели: Руководство по последовательному программированию для операционных систем POSIX

Мне пришлось кое-что сделать последовательный порт взаимодействовал совсем недавно, и эта библиотека работала нормально, что может служить другим примером.

1
ответ дан 17 December 2019 в 18:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: