如何在Linux的串行端口设备上设置非标准波特率? [英] How to set a non-standard baudrate on a serial port device on Linux?

查看:587
本文介绍了如何在Linux的串行端口设备上设置非标准波特率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux上设置自定义波特率的方式有哪些?

What are the ways of setting custom baudrates on Linux?

此问题的答案必须位于高于系统调用级别的用户级低级API(ioctl等)级别.至少在以下情况下应该有用:

An answer to this question must be at a level of userland low-level APIs (ioctl, etc.) above the level of a syscall. It should be useful in these circumstances at least:

  1. 编写使用串行端口的基于C的低级用户域代码,

  1. Writing low-level C-based userland code that uses serial ports,

写出抽象串口功能的库

编写内核串行端口驱动程序.

Writing kernel serial port drivers.

推荐答案

不幸的是,事情取决于驱动程序.好的驱动程序将实现以下所有方法.错误的驱动程序将仅实现某些方法.因此,您需要全部尝试.以下所有方法均在 linux/drivers/tty/serial/serial_core.c .

Things are, unfortunately, driver-dependent. Good drivers will implement all of the methods below. Bad drivers will implement only some of the methods. Thus you need to try them all. All of the methods below are implemented in the helper functions in linux/drivers/tty/serial/serial_core.c.

有以下4种选择.

  1. tty->termios->c_cflag中设置标准波特率.您可以选择:

  1. Standard baud rates are set in tty->termios->c_cflag. You can choose from:

    B0
    B50
    B75
    B110
    B134
    B150
    B200
    B300
    B600
    B1200
    B1800
    B2400
    B4800
    B9600
    B19200
    B38400
    B57600
    B115200
    B230400

  • 如果您需要上面未列出的费率,例如460800(根据源代码注释,这是内核开发人员希望消亡的不推荐使用的hack):

  • If you need rates not listed above, e.g. 460800 (this is a deprecated hack that the kernel developers wish to die, per the source code comments):

    • tty->termios->c_cflag速度设置为B38400

    使用(struct serial_struct)设置如下的TIOCSSERIAL ioctl调用:

    call TIOCSSERIAL ioctl with (struct serial_struct) set as follows:

    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

    This sets alternate speed to HI: 57600, VHI: 115200, SHI: 230400, WARP: 460800

    您可以使用alt_speed设置任意速度,如下所示:

    You can set an arbitrary speed using alt_speed as follows:

    • tty->termios->c_cflag速度设置为B38400.这与您选择的速度无关!

    • Set tty->termios->c_cflag speed to B38400. This is unrelated to the speed you chose!

    tty->alt_speed中设置预期速度.在alt_speed==0时会被忽略.

    Set the intended speed in tty->alt_speed. It gets ignored when alt_speed==0.

    您还可以通过如下设置自定义除数来设置任意速度:

    You can also an arbitrary speed rate by setting custom divisor as follows:

    • tty->termios->c_cflag速度设置为B38400.这与您选择的速度无关!

    • Set tty->termios->c_cflag speed to B38400. This is unrelated to the speed you chose!

    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
    

  • 使用以下设置的struct serial_struct调用TIOCSSERIAL ioctl:

  • Call TIOCSSERIAL ioctl with struct serial_struct set as follows:

    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
    

  • 该怎么做?首先通过调用TIOCGSERIAL ioctl填充结构(包括所需的baud_base).然后修改它以指示新的波特率,并用TIOCSSERIAL设置它:

    How to do it? First get the structure filled (including baud_base you need) by calling TIOCGSERIAL ioctl. Then modify it to indicate the new baudrate and set it with 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;
       }
    

    这篇关于如何在Linux的串行端口设备上设置非标准波特率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆