Правильная последовательность инициализации для последовательного порта Linux - PullRequest
6 голосов
/ 06 июня 2010

Я написал приложение, которое должно использовать последовательные порты в Linux, особенно ttyUSB.Операции чтения и записи выполняются стандартными циклами select () / read () и write (), и в них, вероятно, нет ничего плохого, но код инициализации (или отсутствие какой-либо его части) повреждает что-то в подсистеме 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 .

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

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

Ответы [ 5 ]

2 голосов
/ 06 июня 2010

Удар по WARN_ON строке может означать, что вы столкнулись с ошибкой ядра. Я знаю, что в последнее время проделана большая работа по улучшению драйвера USB-последовательного интерфейса; Я предлагаю попробовать новое ядро ​​и / или спросить в списке рассылки linux-usb@vger.kernel.org.

1 голос
/ 06 июня 2010

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

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

0 голосов
/ 06 июля 2011

Хорошо. Это не может быть идеальным решением ... это определенно не так. Я только что выкинул конвертер FT232 (на самом деле его поджарил) и использовал один на базе CP2102. Сейчас он работает (и в 6 раз дешевле).

0 голосов
/ 06 июня 2010

Возможно, вы захотите попробовать:

  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 голосов
/ 06 июня 2010

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

...