在Linux下为FTDI虚拟串口指定非标准波特率

时间:2010-07-07 06:43:07

标签: linux serial-port virtual-serial-port

我有一个USB设备,我试图通过ftdi_sio内核模块提供的虚拟串口进行通信。但是,我在设置端口的波特率为14400时遇到了一些麻烦:

  • termios.h未指定14400的常量,因此我无法使用cfsetispeedcfsetospeed
  • 在ftdi_sio内核模块的源代码中,波特率设置为24000000,似乎没有办法改变它。这意味着我无法使用TIOCSSERIAL ioctl的自定义除数,并以此方式获得14400波特率。
  • 模块源有一个注释,听起来好像设置端口alt_speed结构的tty_struct成员到14400会做我想要的,但似乎没有任何办法给定现有接口,将其设置为14400。

有没有人对此有任何想法?通过破解内核模块来解决这个问题非常容易,但我真的在寻找一种不需要更改内核的解决方案。

2 个答案:

答案 0 :(得分:4)

您无法更改波特率,我认为它与硬件相关。所以弄乱模块对你没什么好处。在第三点中,您只讨论了设置自定义波特率的第一种方法,您需要访问tty->alt_speed。似乎没有直接从用户空间设置tty结构的接口,至少不能使用ftdi_sio驱动程序 但是,评论中解释了另一种方法:

     * 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

你试过吗?

答案 1 :(得分:3)

Shodanex的解决方案适用于Linux下的NDI Polaris Spectra(波特率为1.2mbps)。按照规定,使用B38400打开串行设备(/ dev / ttyUSB0),

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

然后执行:

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