Linux C++ Serial Writing:只写一个字符

Linux C++ Serial Writing: Only one character written

本文关键字:一个 字符 Serial C++ Writing Linux      更新时间:2023-10-16

我正在尝试修改此处编写的代码:Linux C 串行端口读取/写入,以便我可以通过串行(带有 USB 适配器(连接控制 LED 闪光灯单元。但是,当我尝试将 12 个命令写入设备,然后使用 GTKterm 和示波器检查 LED 状态时,设备似乎只接收第一个项,即它正在接收命令("10000000000"(。我相信端口设置是正确的(尽管我可能完全错误(,并正确附加了以下在GTKterm中运行的命令的图像!http://oi59.tinypic.com/27wrexx.jpg。有谁知道为什么会发生这种情况?非常感谢山 姆

我的代码:

int flasher::allon(){
  int USB = open( "/dev/ttyUSB0", O_RDWR| O_NOCTTY );
  struct termios tty;
  struct termios tty_old;
  memset (&tty, 0, sizeof tty);
  /* Error Handling */
  if ( tcgetattr ( USB, &tty ) != 0 )
    {
      cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << endl;
    }
  /* Save old tty parameters */
  tty_old = tty;
  /* Set Baud Rate */
  cfsetospeed (&tty, (speed_t)B9600);
  cfsetispeed (&tty, (speed_t)B9600);
  /* Setting other Port Stuff */
  tty.c_cflag     &=  ~PARENB;        // Make 8n1
  tty.c_cflag     &=  ~CSTOPB;
  tty.c_cflag     &=  ~CSIZE;
  tty.c_cflag     |=  CS8;  
  tty.c_cflag     &=  ~CRTSCTS;       // no flow control
  tty.c_cc[VMIN]      =   1;                  // read doesn't block
  tty.c_cc[VTIME]     =   5;                  // 0.5 seconds read timeout
  tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines
  /* Make raw */
  cfmakeraw(&tty);
  /* Flush Port, then applies attributes */
  tcflush( USB, TCIFLUSH );
  if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
     {
       cout << "Error " << errno << " from tcsetattr" << endl;
     }
  unsigned char cmd[] = "111111111111 rn";
  int n_written = 0;
  do {
    n_written += write( USB, &cmd[n_written], 1 );
  }
  while (cmd[n_written-1] != 'r' && n_written > 0);
  int n = 0;
  char buf = '';
  /* Whole response*/
  std::string response;
  do
    {
      n = read( USB, &buf, 1 );
      response.append( &buf );
    }
  while( buf != 'r' && n > 0);
  if (n < 0)
    {
      cout << "Error reading: " << strerror(errno) << endl;
    }
  else if (n == 0)
    {
      cout << "Read nothing!" << endl;
    }
  else
    {
      cout << "Response: " << response<<endl;
    }
  return 0;
}

由于这个原因,你的代码肯定不能工作

string有一个追加函数,该函数接受 char*,但它需要一个以 null 结尾的字符串。你的 buf 只是一个字符,所以如果 read(( 确实在其中放了一个字符,则无法保证内存中它后面的内容,因此您没有适当的以 null 结尾的字符串,而是未定义的行为。

您可能应该提供一个超过 1 个字符的缓冲区,然后使用一个需要长度的 append 版本,传入 n。

否则替换

response.append( &buf );

response.push_back( buf );

这可能有效,但效率可能低于使用多字符缓冲区。在附加之前,您可能也应该检查read的结果。就代码而言,如果read失败,您仍然会追加。

此语句,如果有效,应切换 while 子句的顺序

while (cmd[n_written-1] != 'r' && n_written > 0);

如果n_written不是> 0,则 LHS 是未定义的行为。所以

while ( n_written > 0 && cmd[n_written-1] != 'r');

您确定这是终止循环的正确条件吗?我认为r是某种"消息结束"角色。

如果write()返回 -1,则不一定会将n_written推到 0 或低于 0。

相关文章: