在 Linux 上设置自定义波特率的方法有哪些?
这个问题的答案必须在ioctl
系统调用级别之上的用户级低级 API(等)级别。它至少在这些情况下应该是有用的:
编写使用串行端口的基于 C 的低级用户态代码,
编写抽象串行端口功能的库,
编写内核串行端口驱动程序。
在 Linux 上设置自定义波特率的方法有哪些?
这个问题的答案必须在ioctl
系统调用级别之上的用户级低级 API(等)级别。它至少在这些情况下应该是有用的:
编写使用串行端口的基于 C 的低级用户态代码,
编写抽象串行端口功能的库,
编写内核串行端口驱动程序。
不幸的是,事情取决于驱动程序。好的驱动程序将实现以下所有方法。糟糕的驱动程序只会实现其中的一些方法。因此,您需要全部尝试。以下所有方法都在linux/drivers/tty/serial/serial_core.c中的辅助函数中实现。
有以下 4 种选择。
标准波特率设置在tty->termios->c_cflag
. 您可以选择:
B0
B50
B75
B110
B134
B150
B200
B300
B600
B1200
B1800
B2400
B4800
B9600
B19200
B38400
B57600
B115200
B230400
如果您需要上面未列出的费率,例如 460800(根据源代码注释,这是内核开发人员希望放弃的已弃用的 hack):
将tty->termios->c_cflag
速度设置为B38400
调用TIOCSSERIAL
ioctl 并将 (struct serial_struct) 设置如下:
serial->flags & ASYNC_SPD_MASK == ASYNC_SPD_[HI, VHI, SHI, WARP]
// this is an assertion, i.e. what your code must achieve, not how
这会将备用速度设置为 HI: 57600, VHI: 115200, SHI: 230400, WARP: 460800
您可以使用 alt_speed 设置任意速度,如下所示:
将tty->termios->c_cflag
速度设置为B38400
。这与您选择的速度无关!
在 中设置预期速度tty->alt_speed
。时被忽略alt_speed==0
。
您还可以通过设置自定义除数来任意速度速率,如下所示:
将tty->termios->c_cflag
速度设置为B38400
。这与您选择的速度无关!
bool set_baudrate(int fd, long baudrate) {
struct termios term;
if (tcgetattr(fd, &term)) return false;
term.c_cflag &= ~(CBAUD | CBAUDEX);
term.c_cflag |= B38400;
if (tcsetattr(fd, TCSANOW, &term)) return false;
// cont'd below
使用 set调用TIOCSSERIAL
ioctl,struct serial_struct
如下所示:
serial->flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST
serial->custom_divisor == serial->baud_base / your_new_baudrate
// these are assertions, i.e. what your code must achieve, not how
怎么做?baud_base
首先通过调用TIOCGSERIAL
ioctl来填充结构(包括你需要的)。然后修改它以指示新的波特率并将其设置为TIOCSSERIAL
:
// cont'd
struct serial_struct serial;
if (ioctl(fd, TIOCGSERIAL, &serial)) return false;
serial->flags &= ~ASYNC_SPD_MASK;
serial->flags |= ASYNC_SPD_CUST;
serial->custom_divisor = serial->baud_base / baudrate.
if (ioctl(fd, TIOCSSERIAL, &serial)) return false;
return true;
}