Linux 设置更高的波特率和相关设置
Linux set higher baud rate and associated settings
输入硬件:BeagleBone Black,上面有一些 GNU/Linux 发行版 运行。
我想要实现的目标:我想将一些 UART
外围设备设置为 921600
波特值,并能够设置其他串行相关设置(例如 start/stop 位、奇偶校验、数据位、硬件流量控制等)。
到目前为止,在Linux中,我至少找到了三种配置此参数的方法:
- 使用
struct termios
形式 termios.h
头文件。
- 使用
asm/termios.h
头文件中的 struct termios2
。
- 使用
stty(1)
GNU/Linux 实用程序。
问题是什么:
使用第一种方法我不能使用 921600
波特率值(没有定义这么高的值,它只能达到 230400 baud
。所以这个方法行不通.
第二种方法为我提供了一种更改自定义 baud
速率值的方法,但也很棘手,因为它不提供 tcgetattr()
、tcsendbreak()
、tcflush()
,等等。这个函数存在于第一个描述的方法中,我不能同时包含头文件 termios.h
和 asm/termios.h
因为 (1).
最后一种方法也不起作用,或者至少它不适用于我想做的所有设置。这是我正在使用的当前方法,我正在打开目标文件,我得到一个文件描述符,我为该文件描述符设置了通信参数(波特率(首先我设置了一个较低的值),奇偶校验,start/stop 位等)使用第一种方法,然后我使用 stty(1)
实用程序将波特率值更改(覆盖)为 921600
(我调用 system(...)
函数来执行此操作) .
例如,如果我想更改 HW flow control
,此方法将不起作用(它不会覆盖该设置,就像 baud
值一样)。
解决方案是什么?
像这样把两种设置参数的方式混合到一个UART
通信link可以吗?
恕我直言,在 C 或 C++ 程序中使用 system
和 stty
不是 方法(system
被称为一开始是糟糕的安全措施)。
阅读您的相关问题后,我的建议是仅在您的主模块、命名空间或 class 中声明 声明 一些您想要的所有功能的包装函数使用 termios.h 和 asm/termios.h.
然后在两个不同的编译单元(c 或 c++ 源文件)中 定义 它们,首先处理 termios.h,后者处理 asm/termios。 h
如果这不起作用,最后一种方法是将来自 termios.h 和 asm/termios.h 的声明小心地合并到自定义 local_termios.h 中,并包含它。这当然会导致不可移植的代码,但是无论如何,一旦你使用 asm/termios.h 你就会失去兼容性。
您可以使用 setserial 控制台实用程序:
1) 从 setserial
输出中获取 baud_base 值
setserial -a /dev/<...>
2) 计算除数 = baud_base / desired_baud_rate
例如,如果 baud_base = 3000000 (3MHz):
baud_rate = 115200 -> divisor = 26.04 (approximately 26)
baud_rate = 230400 -> divisor = 13.02 (approximately 13)
baud_rate = 921600 -> divisor = 3.26
3.26 对于设置 divisor=3 来说太多了,对于设置 divisor=4 来说太少了。
因此,在这种情况下,由于硬件限制,您不能使用 baud_rate=921600。
您可以选择除数=3 (baud_rate=1000000) 或除数=4 (baud_rate=750000)。这些波特率不是标准的,但可能。
stty -F /dev/<...> 9600 -icrnl -ixon -crtscts -parenb # desired UART settings
setserial /dev/<...> spd_cust # use custom value for divisor
setserial /dev/<...> divisor 3 # set custom value for divisor
stty -F /dev/<...> 38400 # activate setserial settings
# now baud_rate is (baud_base / divisor)
输入硬件:BeagleBone Black,上面有一些 GNU/Linux 发行版 运行。
我想要实现的目标:我想将一些 UART
外围设备设置为 921600
波特值,并能够设置其他串行相关设置(例如 start/stop 位、奇偶校验、数据位、硬件流量控制等)。
到目前为止,在Linux中,我至少找到了三种配置此参数的方法:
- 使用
struct termios
形式termios.h
头文件。 - 使用
asm/termios.h
头文件中的struct termios2
。 - 使用
stty(1)
GNU/Linux 实用程序。
问题是什么:
使用第一种方法我不能使用 921600
波特率值(没有定义这么高的值,它只能达到 230400 baud
。所以这个方法行不通.
第二种方法为我提供了一种更改自定义 baud
速率值的方法,但也很棘手,因为它不提供 tcgetattr()
、tcsendbreak()
、tcflush()
,等等。这个函数存在于第一个描述的方法中,我不能同时包含头文件 termios.h
和 asm/termios.h
因为 (1).
最后一种方法也不起作用,或者至少它不适用于我想做的所有设置。这是我正在使用的当前方法,我正在打开目标文件,我得到一个文件描述符,我为该文件描述符设置了通信参数(波特率(首先我设置了一个较低的值),奇偶校验,start/stop 位等)使用第一种方法,然后我使用 stty(1)
实用程序将波特率值更改(覆盖)为 921600
(我调用 system(...)
函数来执行此操作) .
例如,如果我想更改 HW flow control
,此方法将不起作用(它不会覆盖该设置,就像 baud
值一样)。
解决方案是什么?
像这样把两种设置参数的方式混合到一个UART
通信link可以吗?
恕我直言,在 C 或 C++ 程序中使用 system
和 stty
不是 方法(system
被称为一开始是糟糕的安全措施)。
阅读您的相关问题后,我的建议是仅在您的主模块、命名空间或 class 中声明 声明 一些您想要的所有功能的包装函数使用 termios.h 和 asm/termios.h.
然后在两个不同的编译单元(c 或 c++ 源文件)中 定义 它们,首先处理 termios.h,后者处理 asm/termios。 h
如果这不起作用,最后一种方法是将来自 termios.h 和 asm/termios.h 的声明小心地合并到自定义 local_termios.h 中,并包含它。这当然会导致不可移植的代码,但是无论如何,一旦你使用 asm/termios.h 你就会失去兼容性。
您可以使用 setserial 控制台实用程序:
1) 从 setserial
输出中获取 baud_base 值
setserial -a /dev/<...>
2) 计算除数 = baud_base / desired_baud_rate
例如,如果 baud_base = 3000000 (3MHz):
baud_rate = 115200 -> divisor = 26.04 (approximately 26)
baud_rate = 230400 -> divisor = 13.02 (approximately 13)
baud_rate = 921600 -> divisor = 3.26
3.26 对于设置 divisor=3 来说太多了,对于设置 divisor=4 来说太少了。
因此,在这种情况下,由于硬件限制,您不能使用 baud_rate=921600。 您可以选择除数=3 (baud_rate=1000000) 或除数=4 (baud_rate=750000)。这些波特率不是标准的,但可能。
stty -F /dev/<...> 9600 -icrnl -ixon -crtscts -parenb # desired UART settings
setserial /dev/<...> spd_cust # use custom value for divisor
setserial /dev/<...> divisor 3 # set custom value for divisor
stty -F /dev/<...> 38400 # activate setserial settings
# now baud_rate is (baud_base / divisor)