c - 如何使用 Termios 通过 socat 数据传输循环发送字节

标签 c serial-port pty termios socat

我正在尝试编写一个简单的程序,通过串行连接发送字节。我使用 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 并且当回显输出时会给出“abc”。

运行我的程序会得到以下输出:

/dev/pts/2
Port opened successfully
BaudRate = 13
StopBits = 1
Parity = Odd
Bytes written: 3

所以我知道字节在某处,因为 write() 不返回 -1。

最佳答案

您的代码适用于我的真实和虚拟串口。

需要注意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" 编译),您将在运行 的终端上看到 abc

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

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

关于c - 如何使用 Termios 通过 socat 数据传输循环发送字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57084952/

相关文章:

c - 从 C super 终端读取数据 (ASCII )

Python + Arduino 与 Mac OS X

Java : threaded serial port read with Java. util.concurrent 线程访问

python - 如何向终端应用程序编写透明包装器?

c - 写入 `forkpty`子进程: `less` pager

c - 从C中的字符串中删除字符

gcc c 编译器中的 cswtch 生成

c - 出队功能不起作用

c - 如何检测指定的终端设备进行交互工作

c - 使用 execvp 传递参数