Pregunta

Escribí una aplicación que debe usar puertos serie en Linux, especialmente los TTYUSB. Las operaciones de lectura y escritura se realizan con Standard Select ()/Read () Loop y Write (), y probablemente no hay nada malo en ellas, pero el código de inicialización (o ausencia de alguna parte) daña algo en el subsistema TTY. Aquí está:


  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);
  }

Otro tcsetattr(_fd, TCSANOW, &_termios) Se sienta en el destructor, pero es irrelevante.

Con o sin esta inicialización de termios, las cosas extrañas suceden en el sistema Después de que la aplicación sale. A veces sencillo cat (o hd) sale inmediatamente imprimiendo nada o las mismas cosas cada vez, a veces está esperando y no muestra ninguno de los datos que seguramente se envían al puerto; y close() (read() también, pero no cada vez) emite un extraño WARNING a dmesg Refiriéndose a USB-serial.c.

Revisé las decenas de hardware y firmware de veces (incluso en diferentes máquinas) y estoy seguro de que está funcionando según lo previsto; Además, despojé el firmware para imprimir el mismo mensaje una y otra vez.

¿Cómo puedo usar el puerto serie sin destruir nada? Gracias.

¿Fue útil?

Solución 5

Bueno. Puede que esta no sea una solución perfecta ... definitivamente no lo es. Acabo de echar un convertidor FT232 (en realidad frito), y usé uno basado en CP2102. Simplemente funciona ahora (y también es 6 veces más barato).

Otros consejos

Golpeando un WARN_ON línea puede que significa que has golpeado un error de kernel. Sé que últimamente ha habido mucho trabajo para mejorar el controlador USB-Serial; Sugiero probar un kernel más nuevo y/o preguntar en la lista de correo de linux-usb@vger.kernel.org.

No estoy seguro de qué está mal con su fragmento de código allí, pero esto podría ser útil, si aún no lo ha visto: Guía de programación en serie para sistemas operativos POSIX

Tuve que hacer un poco de interfaz de puertos en serie recientemente y esta biblioteca Funcionó bien, eso podría servir como otro ejemplo.

Solo como una nota al margen realmente, su error verifica open No es del todo correcto: las condiciones de error se señalan por un valor de retorno de -1. (0 es un FD perfectamente válido, generalmente conectado a Stdin).

Es posible que desee probar:

  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);
}

Esto hace que cualquier campo inesperado de termios En su sistema, obtenga valores algo razonables.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top