Правильная последовательность инициализации последовательного порта Linux
Я написал приложение, которое должно использовать последовательные порты в 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 ответов
удара WARN_ON
строка может означает, что вы попали в баг ядра. Я знаю, что в последнее время было много работы по улучшению USB-последовательного драйвера; я предлагаю попробовать более новое ядро и / или попросить linux-usb@vger.kernel.org список рассылки.
Я не уверен, что не так с вашим фрагментом кода, но это может пригодиться, если вы его еще не видели:руководство по последовательному программированию для операционных систем POSIX
Мне пришлось сделать некоторые последовательный порт сопряжения совсем недавно и библиотека работало нормально, что может служить еще одним примером.
Так же, как Примечание действительно, ваша проверка ошибок на open
не совсем правильно-условия ошибки сигнализируются возвращаемым значением -1. (0 является совершенно действительным fd, обычно подключенным к stdin.)
вы можете попробовать:
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
в вашей системе получите несколько разумных значений.
ОК. Это может быть не идеальным решением... определенно нет. Я просто выбросил конвертер FT232 (обжарил его, на самом деле) и использовал CP2102-based. Он просто работает сейчас (а также в 6 раз дешевле).