如何使用Termios在socat数据传输循环中发送字节

3

我正在尝试编写一个简单的程序,通过串行连接发送字节。我使用socat创建了一个数据传输循环,如下所示:

$ socat -d -d pty pty

这会在 /dev/pts/2 和 /dev/pts/0 之间创建一个数据传输循环。当我尝试在我的C程序中使用termios写入一些字节时,我成功地通过open()打开了串行连接。然后我使用write()写入一些字节并接收到写入的字节数。但是,当我监听另一个终端时,我没有看到任何输出。我使用以下命令尝试在另一个终端中监听:

$ cat /dev/pts/0 | xxd
$ read -r line < /dev/pts/0
$ echo $line

我知道我的 socat 连接是正常的,因为当我发送字节并在另一端监听时,我可以正常地接收到它们。
#define BAUD_RATE B9600
#define PORT_NAME "/dev/pts/2"

/* Serial Connection Manager */
struct termios tty;
int fd;

int main(){
  /*
  O_RDWR: read/write access to serial port
  O_NOCTTY: No terminal will control the process
  O_NDELAY: Non-blocking, returns immediately
  */
  fd = open(PORT_NAME, O_RDWR | O_NOCTTY | O_NDELAY);
  printf("%s\n", PORT_NAME);
  if (fd == -1) {
    printf("Error in opening serial port\n");
    return -1;
  }
  else
    printf("Port opened successfully\n");

  tcgetattr(fd, &tty); // get current attrs of serial port
  // raw mode of terminal driver
  //cfsetispeed(&tty, BAUD_RATE);
  //cfsetospeed(&tty, BAUD_RATE);
  cfmakeraw(&tty);

  // set additional control modes
  cfsetspeed(&tty, (speed_t) BAUD_RATE);
  tty.c_cflag &= ~CSTOPB; //1 stop bit
  tty.c_cflag &= ~CRTSCTS; //disable hardware flow control
  tty.c_cflag |= CLOCAL; //ignore modem control lines
  tty.c_cflag |= CREAD; //enable receiver

  if((tcsetattr(fd, TCSANOW, &tty)) != 0){
    printf("Error in setting attributes\n");
    close(fd);
    return -1;
  }
  else
    printf("BaudRate = %d\nStopBits = 1\nParity = Odd\n", BAUD_RATE);

  sleep(1); // wait for configuration
  tcflush(fd, TCIOFLUSH);

  char buf[3] = "abc";
  int bytes_written = write(fd, buf, 3);
  printf("Bytes written: %d", bytes_written);
  close(fd);
  return 0;
}

我希望能够通过以下命令监听字节流: $ read -r output < /dev/pts/0 并且当输入 "echo output" 后,能够输出 "abc"。
运行我的程序将得到以下输出:
/dev/pts/2
Port opened successfully
BaudRate = 13
StopBits = 1
Parity = Odd
Bytes written: 3

我知道字节正在某个地方传输,因为 write() 没有返回 -1。

1个回答

0

你的代码在真实和虚拟串口上都能正常工作。

你需要注意 socat 的输出:

$ socat -d -d pty pty
2019/07/18 07:55:45 socat[8144] N PTY is /dev/pts/2
2019/07/18 07:55:45 socat[8144] N PTY is /dev/pts/3
2019/07/18 07:55:45 socat[8144] N starting data transfer loop with FDs [5,5] and [7,7]

然后在这对中的第一个端口上进行监听:

$ cat /dev/pts/2

运行您的代码(使用PORT_NAME "/dev/pts/2"编译),您将在运行cat的终端上看到abc

您还可以尝试使用minicom或其他任何您喜欢的终端连接到/dev/pts/2/dev/pts/3,您将看到输出:

$ minicom -D /dev/pts/2 -b 9600

如果我正在向/dev/pts/2写入字节,那么我不应该能够监听/dev/pts/3以观察输出吗(因为这是它们之间的数据传输连接)?当我向/dev/pts/2回显时,我可以cat /dev/pts/3来查看我回显的内容。 - BreakfastCalzone
此外,我已经尝试同时监听 /dev/pts/2 和 /dev/pts/3,但仍然无法正常工作。 - BreakfastCalzone
使用minicom,我可以在两个端口上看到数据。如果我使用cat命令,我只能看到/dev/pts/2上的数据。 - Marcos G.
哦,好的,它可以在minicom上工作,我只能看到它在未被写入的端口上(这是预期的行为)。谢谢!不确定为什么cat和read不起作用。 - BreakfastCalzone
是的,这和我看到的一致。我也不确定为什么“cat”会这样工作。我从来没有喜欢过它。 - Marcos G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接