【问题标题】:Serial port not reading串口不读
【发布时间】:2025-12-22 22:05:13
【问题描述】:

我在 Linux 上从串行端口读取时遇到了这个奇怪的问题。大约 50% 的时间,当我从串口读取数据时,我不会从串口取回任何数据,但如果我使用 GTKTerm,我会在 100% 的时间里取回数据。我仔细检查了我的设置,我使用的终端设置与 GTKTerm 使用的完全相同,所以我对为什么会发生这种情况感到困惑。我唯一能想到的是端口设置为规范模式,而不是原始模式,但我正确设置了它 - 我正在读取的设备不会用所有命令发回换行符。但是,当设备发送回带有换行符的命令时,一切正常。

这是我正在使用的代码:

int fd = open(serial_port, O_RDWR );
if( fd < 0 ){
    perror("open");
}

//Set the serial port settings
struct termios newio;
if( tcgetattr( fd, &newio ) < 0 )
    perror("tcgetattr");

if( cfsetospeed( &newio, B9600 ) < 0 )
    perror("cfsetospeed");

newio.c_cflag &= ~CSTOPB;
newio.c_cflag &= ~CSIZE;
newio.c_cflag |= CS8;

newio.c_cflag |= CREAD;
newio.c_iflag |= IGNPAR;
newio.c_iflag |= IGNBRK;
newio.c_iflag &= ~BRKINT;
newio.c_iflag &= ~ICRNL;
newio.c_iflag &= ~IXON;
newio.c_cflag |= CLOCAL;
newio.c_oflag = 0;
newio.c_lflag = 0;
newio.c_cc[VTIME] = 0;
newio.c_cc[VMIN] = 1;
if( tcsetattr( fd, TCSANOW, &newio ) < 0 )
    perror("tcsetattr");
tcflush( fd, TCOFLUSH );
tcflush( fd, TCIFLUSH );

阅读代码(在单独的线程中)

void* thr(void* ign){
    char buffer[10];
    while( 1 ){
            int got = read(fd, buffer, 10);
            buffer[got] = 0;
            printf("got %s\n", buffer);
    }
}

【问题讨论】:

  • 您能否提供一个用于从该 fd 读取/写入的代码示例?您可能还想strace GTKTerm 和您的代码,并从中挑选出TCSETS ioctl 调用进行比较。
  • @rm5248:配置端口的代码似乎没问题。也许如何完成 i/o 是问题所在。另外,请务必仔细比较端口设置与stty -a -F /dev/ttyWhatever 在您的程序打开时和 GTK 打开时是否有任何不同。
  • 好吧,在检查了 stty 之后,我所拥有的和 GTKTerm 所拥有的之间的唯一区别是 hupcl,这无关紧要,因为我所连接的仅使用传输/接收线路。我在阅读代码中编辑,编写代码基本相同。

标签: linux serial-port


【解决方案1】:

嗯,我发现了问题。

出于某种奇怪的原因,我发送到的设备似乎没有大缓冲区或其他东西;事实证明,当我一次将命令作为字符串发送时,我不会总是得到回复。在发送字符之间睡觉可以解决问题(尽管我承认,这不是一个很好的解决方案)。可能发生的事情是我在某些时候被打断了,这将为设备提供足够的时间来处理它的一些输入。 GTKTerm 将在接收到每个字符时将其发送出去,并且无法以足够快的速度键入以发生此错误。

【讨论】: