Especificación de la velocidad de transmisión no estándar para el puerto serie virtual FTDI bajo Linux

StackOverflow https://stackoverflow.com/questions/3192478

Pregunta

Tengo un dispositivo USB que estoy tratando de comunicarse con más de un puerto serie virtual proporcionada por el ftdi_sio módulo del kernel. Sin embargo, estoy teniendo un poco de ajuste de la velocidad de transmisión del puerto molestia de 14400:

  • termios.h no especifica una constante de 14400, así que no puedo usar cfsetispeed y cfsetospeed.
  • En el origen de la ftdi_sio módulo del kernel, la base de transmisión se establece en 24 millones y no parece ser una manera de cambiarlo. Esto significa que no pueden utilizar un divisor personalizado con el ioctl TIOCSSERIAL y obtener una tasa de 14.400 baudios de esa manera.
  • La fuente módulo tiene un comentario haciendo que suene como la configuración del miembro de la estructura alt_speed tty_struct para que el puerto 14400 que hacer lo que quiera, pero no parece haber ninguna manera de ponerlo en 14400 dada la existente interfaces.

¿Alguien tiene alguna idea acerca de esto? Sería bastante fácil de solucionar este problema mediante piratería informática hasta el módulo del kernel, pero estoy realmente en busca de una solución que no requiere cambios en el kernel.

¿Fue útil?

Solución

No se puede cambiar de base de transmisión, supongo que es relacionado con el hardware. Así que jugar con el módulo no le hará ningún bien. En su tercer punto en el que sólo se habla de la primera método propuesto para establecer una velocidad de transmisión personalizada, donde se necesita para acceder a la tty->alt_speed. Parece que no hay ninguna interfaz directa al conjunto TTY estructura de espacio de usuario, al menos no con el conductor ftdi_sio.
Sin embargo, hay otro método explicado en los comentarios:

     * 3. You can also set baud rate by setting custom divisor as follows
     *    - set tty->termios->c_cflag speed to B38400
     *    - call TIOCSSERIAL ioctl with (struct serial_struct) set as
     *      follows:
     *      o flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST
     *      o custom_divisor set to baud_base / your_new_baudrate

¿Ha probado?

Otros consejos

funciona la solución de Shodanex con un NDI Polaris Spectra (1,2Mbps baudios) bajo Linux. Como se especifica, abra el dispositivo serie (/ dev / ttyUSB0) con B38400,

int port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
tcgetattr(port,&g_initialAtt);// save this to restore later
newAtt=g_initialAtt;
newAtt.c_cflag = B38400 | CS8 | CLOCAL | CREAD; 
cfmakeraw(&newAtt);
tcsetattr(port,TCSANOW,&newAtt);

A continuación, ejecute:

if(ioctl(port, TIOCGSERIAL, &sstruct) < 0){
    printf("Error: could not get comm ioctl\n"); 
    exit(0); 
}
sstruct.custom_divisor = custDiv;
//sstruct.flags &= 0xffff ^ ASYNC_SPD_MASK; NO! makes read fail.
sstruct.flags |= ASYNC_SPD_CUST; 
if(ioctl(port, TIOCSSERIAL, &sstruct) < 0){
    printf("Error: could not set custom comm baud divisor\n"); 
    exit(0); 
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top