如何在linux上使用串口设备

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在linux上使用串口设备相关的知识,希望对你有一定的参考价值。

简单的运行 dmesg 命令
$ dmesg | grep tty
输出:
[ 37.531286] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 37.531841] 00:0b: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 37.532138] 0000:04:00.3: ttyS1 at I/O 0x1020 (irq = 18) is a 16550A

setserial 命令
setserial 是一个程序用于设定并/或报告某个串口关联的配置信息。该信息包括串口用到的I/O 端口和中断号,以及Break键是否应被解释为Secure Attention Key 等等。 仅仅是输出如下的命令:
$ setserial -g /dev/ttyS[0123]
输出:
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x1020, IRQ: 18
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3

带-g选项的setserial帮助找到你的Linux板子上的物理串口。
Linux 串口控制台程序
一旦串口被确定了,你就能使用许多的工具来配置Linux板子:
minicom- 用于控制modem和连接到dump 设备的最好的串口通信程序。
wvidial or other GUI dial up networking program - 一个内建智能PPP 拨号器。
getty / agetty - agetty 打开一个 tty 端口, 提示登录名称并调用 /bin/login 命令。
grub / lilo configuration - 配置串口为系统控制台。
参考技术A 需要驱动 pl2303 芯片的带 linux 驱动

Linux打开设备时串口缓冲区不为空

【中文标题】Linux打开设备时串口缓冲区不为空【英文标题】:Linux serial port buffer not empty when opening device 【发布时间】:2011-11-10 18:55:42 【问题描述】:

我有一个系统,在该系统中,我发现串行端口的异常行为是我没想到的。我以前在使用 USB 转串口适配器时偶尔会看到这种情况,但现在我在本机串口上也看到了这种情况,而且频率要高得多。

系统设置为运行自动化测试,并且在我没有打开端口的情况下,将首先执行一些导致从串行设备输出大量数据的任务。设备也会自行重置。仅连接 tx/rx 线。没有流量控制。

这些任务完成后,测试件打开串口并立即失败,因为它得到了意外的响应。当我重现这个时,我发现如果我在终端程序中打开串行端口,我会看到几千字节的旧数据(似乎是在端口关闭时发送的)立即被清除。关闭此程序后,我就可以按预期运行测试了。

什么可能导致这种情况发生?当设备关闭时,Linux 如何处理缓冲串行端口?如果我打开一个设备,让它发送输出,然后关闭它而不读取它,这会导致同样的问题吗?

【问题讨论】:

【参考方案1】:

即使没有打开,Linux 终端驱动程序也会缓冲输入。这可能是一个有用的功能,特别是如果速度/奇偶校验/等。设置得当。

要复制较小操作系统的行为,请在端口打开后立即从端口读取所有待处理的输入:

...
int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0)
        exit (1);

set_blocking (fd, 0);   // disable reads blocked when no input ready

char buf [10000];
int n;
do 
        n = read (fd, buf, sizeof buf);
 while (n > 0);

set_blocking (fd, 1);  // enable read blocking (if desired)

...  // now there is no pending input



void set_blocking (int fd, int should_block)

        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        
                error ("error %d getting term settings set_blocking", errno);
                return;
        

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = should_block ? 5 : 0; // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                error ("error setting term %sblocking", should_block ? "" : "no");

【讨论】:

我在想可能是这样。那么,为什么我只在部分时间看到这种行为?我正在使用 pyserial 进行测试,并将包含的 miniterm.py 脚本用作交互式终端。有问题的不仅仅是一个串行端口。似乎交替出现。所有串行端口在关闭时都会有数据传入,但只有一个端口会在我打开它时缓冲。也许波特率只是在那个上正确设置? @djs:端口速度是我首先想到的。也可能是gpsdlogind 正在访问封闭的端口以寻找 GPS 设备或登录连接,并推测性地更改端口速度。 这些服务都没有运行。 stty 在我检查之前报告了 115200 的所有端口,发现其中只有一个保留了缓冲区。这是检查波特率的正确工具吗? @djs: stty -F /dev/ttyWhatever 是我一直使用的,从来没有遇到过问题。 我仍然无法很好地解释为什么我通常不会在串行端口上看到这种行为。我已经调整了测试框架以在启动时清除缓冲区,这解决了问题,如果不是我的好奇心......

以上是关于如何在linux上使用串口设备的主要内容,如果未能解决你的问题,请参考以下文章

如何配置使用串口设备登录linux终端Linux Serial Console HOWTO

串口编程 - 虚拟串口设备(串口测试)

Linux打开设备时串口缓冲区不为空

linux 串口设备能否被多次打开

串口windows正常ubuntu

Linux下如何测试及使用USB转串口线