如何在 Linux 上设置自定义波特率?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12646324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:27:45  来源:igfitidea点击:

How can I set a custom baud rate on Linux?

linuxserial-portbaud-rate

提问by Felix

I want to communicate over my serial port on Linux to a device with a non-standard-baud rate that is not defined in termios.h.

我想通过 Linux 上的串行端口与具有未在termios.h.

I tried the "baud rate aliasing"-method from this post, but when I execute my C-program (I've named it "testprogram"), Linux says "testprogram sets custom speed on ttyS0. This is deprecated."

我尝试了这篇文章中的“波特率别名”方法,但是当我执行我的 C 程序(我将其命名为“testprogram”)时,Linux 说"testprogram sets custom speed on ttyS0. This is deprecated."

I did some search on Google, and it seems that there is another (newer?) method to change the baud rate to a non-standard-value: On http://sourceware.org/ml/libc-help/2009-06/msg00016.htmlthe author says that the c_flagof struct termiosmust be OR'd with BOTHER (=CBAUDEX | B0).

我在 Google 上进行了一些搜索,似乎还有另一种(更新的?)方法可以将波特率更改为非标准值:在http://sourceware.org/ml/libc-help/2009-06 /msg00016.html作者说c_flagofstruct termios必须与BOTHER (=CBAUDEX | B0).

With this method the baud rates are set directly in the c_ispeedand c_ospeed-members of the struct termios. However, I don't know how I use this method in my C program. Like the author said, there is no BOTHERdefined/available when I include termios.h, so what should be done to set the baud rate this way?

使用这种方法,波特率直接在 的c_ispeedc_ospeed-members 中设置struct termios。但是,我不知道如何在我的 C 程序中使用这种方法。就像作者说的,BOTHER当我包含时没有定义/可用termios.h,那么这样设置波特率应该怎么做?

How can I set the baud rate to a non-standard-value without changing the kernel?

如何在不更改内核的情况下将波特率设置为非标准值?

回答by Jamey Sharp

BOTHERappears to be available from <asm/termios.h>on Linux. Pulling the definition from there is going to be wildly non-portable, but I assume this API is non-portable anyway, so it's probably no big loss.

BOTHER似乎可从<asm/termios.h>Linux 上获得。从那里提取定义将是非常不可移植的,但我认为这个 API 无论如何都是不可移植的,所以它可能没有太大的损失。

回答by manav m-n

You can set a custom baud rate using the sttycommand on Linux. For example, to set a custom baud rate of 567890 on your serial port /dev/ttyX0, use the command:

您可以使用sttyLinux 上的命令设置自定义波特率。例如,要在串行端口 /dev/ttyX0 上设置自定义波特率 567890,请使用以下命令:

stty -F /dev/ttyX0 567890

回答by Houcheng

There is an serial I/O chip on your motherboard's CPU (16650 UART). This chip uses 8-bit port as control and data bus, and thus you can issue a command to it through writing to this chip through the control and data bus.

主板的 CPU ( 16650 UART)上有一个串行 I/O 芯片。该芯片使用8位端口作为控制和数据总线,因此您可以通过控制和数据总线写入该芯片来向其发出命令。

Usually, an application did the following steps on the serial port

通常,应用程序在串口上做了以下步骤

  1. Set baud rate, parity, encoding, flow control, and starting / ending sequence length during program start. This setup can be done via ioctl to the serial device or 'stty' command. In fact, the stty command uses ioctl to that serial device.
  2. Write characters of data to the serial device and the driver will be writing data charaters to the UART chip through its 8-bit data bus.
  1. 程序启动时设置波特率、奇偶校验、编码、流量控制和开始/结束序列长度。可以通过串行设备的 ioctl 或“stty”命令来完成此设置。事实上,stty 命令使用 ioctl 到那个串行设备。
  2. 向串行设备写入数据字符,驱动程序将通过其 8 位数据总线向 UART 芯片写入数据字符。

In short, you can specify the baud rate only in the STTY command, and then all other options would be kept as default, and it should enough to connect to ohter devices.

简而言之,您只能在STTY命令中指定波特率,然后所有其他选项将保持默认,并且足以连接到其他设备。

回答by dougg3

I noticed the same thing about BOTHER not being defined. Like Jamey Sharp said, you can find it in <asm/termios.h>. Just a forewarning, I think I ran into problems including both it and the regular <termios.h>file at the same time.

我注意到关于 BOTHER 没有被定义的同样的事情。就像 Jamey Sharp 所说的,你可以在<asm/termios.h>. 只是一个预警,我想我同时遇到了包括它和常规<termios.h>文件在内的问题。

Aside from that, I found with the glibc I have, it still didn't work because glibc's tcsetattr was doing the ioctl for the old-style version of struct termios which doesn't pay attention to the speed setting. I was able to set a custom speed by manually doing an ioctl with the new style termios2 struct, which should also be available by including <asm/termios.h>:

除此之外,我发现使用我拥有的 glibc,它仍然无法工作,因为 glibc 的 tcsetattr 正在为不注意速度设置的旧式 struct termios 版本执行 ioctl。我能够通过使用新样式 termios2 结构手动执行 ioctl 来设置自定义速度,该结构也应该通过包含<asm/termios.h>以下内容可用:

struct termios2 tio;

ioctl(fd, TCGETS2, &tio);
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
tio.c_ispeed = 12345;
tio.c_ospeed = 12345;
ioctl(fd, TCSETS2, &tio);

回答by varatis

For Mac users (possibly also for some Linux distributions)

对于 Mac 用户(可能也适用于某些Linux 发行版

stty ospeed 999999

stty ispeed 999999

回答by RichardAshAudacity

dougg3 has this pretty much (I can't comment there). The main additional thing you need to know is the headers which don't conflict with each other but do provide the correct prototypes. The answer is

dougg3 有很多(我不能在那里发表评论)。您需要知道的主要附加事项是彼此不冲突但确实提供正确原型的标头。答案是

#include <stropts.h>
#include <asm/termios.h>

After that you can use dougg3's code, preferably with error checking round the ioctl() calls. You will probably need to put this in a separate .c file to the rest of your serial port code which uses the normal termios to set other parameters. Doing POSIX manipulations first, then this to set the custom speed, works fine on the built-in UART of the Raspberry Pi to get a 250k baud rate.

之后,您可以使用 dougg3 的代码,最好对 ioctl() 调用进行错误检查。您可能需要将它放在一个单独的 .c 文件中,以便使用普通的 termios 设置其他参数的串行端口代码的其余部分。首先进行 POSIX 操作,然后设置自定义速度,在 Raspberry Pi 的内置 UART 上运行良好以获得 250k 波特率。

回答by DeltA

You can just use the normal termios header and normal termios structure (it's the same as the termios2 when using header asm/termios).

您可以只使用普通的 termios 头文件和普通的 termios 结构(当使用头文件 asm/termios 时,它与 termios2 相同)。

So, you open the device using open() and get a file descriptor, then use it in tcgetattr()to fill your termios structure.

因此,您使用 open() 打开设备并获取文件描述符,然后使用它tcgetattr()来填充您的 termios 结构。

Then clear CBAUDand set CBAUDEXon c_cflag. CBAUDEXhas the same value as BOTHER.

然后清除CBAUD和设置CBAUDEXc_cflagCBAUDEX与 BOTHER 具有相同的值。

After setting this, you can set a custom baud rate using normal functions, like cfsetspeed(), specifying the desired baud rate as an integer.

设置后,您可以使用普通函数设置自定义波特率,例如cfsetspeed(),将所需的波特率指定为整数。