VirtualBox 中 linux 上的串口从数据流中过滤掉 0x11

Serial port on linux in VirtualBox filters out 0x11 from data stream

不知道这个问题是VirtualBox的问题还是串口配置的问题。我正在测试一个通过串行端口与特定硬件交互的程序。一切正常,但在从设备接收的数据流中,某些字节未正确接收。特别是 0x11、0x13 丢失,0x0d 被接收为 0x0a。我有一个监视串行端口的串行嗅探器程序,在那里可以看到字节,但是在我的程序中没有看到它是 运行 在 VirtualBox linux 机器中。我需要查看所有没有流量控制的二进制字节。这是我打开串口的方式:

int openPort( char* portname )
{
  int fd;

  fd = open( portname, O_RDWR | O_NOCTTY | O_NDELAY );
  if ( fd == -1 )
  {
      perror( "openPort():" );
      printf( "Unable to open %s\n", portname );
  }
  else
  {
      fcntl( fd, F_SETFL, FASYNC );

      struct termios my_termios;
      struct termios new_termios;

      tcgetattr( fd, &termios_save );
      tcgetattr( fd, &my_termios );
      cfsetispeed( &my_termios, B9600 );
      cfsetospeed( &my_termios, B9600 );
      my_termios.c_cflag &= ~( PARENB | CSTOPB | CSIZE );
      my_termios.c_cflag |= ( CS8 | CREAD );
      my_termios.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
      my_termios.c_oflag &= ~OPOST;
      my_termios.c_cc[VMIN] = 1;
      my_termios.c_cc[VTIME] = 100;   // wait 10 seconds for a character
      tcsetattr( fd, TCSANOW, &my_termios );
      tcgetattr( fd, &new_termios );
      if ( memcmp( &my_termios, &new_termios, sizeof( my_termios ) ) != 0 )
      {
          printf( "Error setting serial port options, aborting\n" );
          close( fd );
          fd = -1;
      }
  }

  return fd;
}

我已经看过各种使用串行端口的指南,包括 Serial Programming Guide for POSIX Operating Systems,这就是我想出的。

0x110x13 是 ASCII XON (DC1, Ctrl-Q)XOFF (DC3, Ctrl-S) 的十六进制值,用于在性能有限的应用程序中提供数据流的步调。

主机串行端口或 VirtualBox 正在解释这些(或只是过滤它们以避免后续解释)。在主机中将端口设置为原始模式。你不说,但如果它是 *nix 的某种风格,那么 stty 可能会有所帮助。

显然我错过了指南中的一个部分。我最初是从一些我现在找不到的示例程序中复制我的初始化代码的,所以我不知道他们是否也遗漏了它,或者我是否在我的副本中遗漏了它。不管怎样,问题出在 c_iflag 的设置上,我最初并没有更改它。添加行:

my_termios.c_iflag &= ~( IXON | IXOFF | IXANY | ICRNL | INLCR | IGNCR );

处理问题。显然软件流控制和 CR->NL 映射是默认启用的。