我可以以伪奇偶校验方式打开伪终端吗?我不断收到无效参数的重新调整

时间:2018-11-05 16:01:08

标签: c gps ntp pty centos6.5

我正在修理一些GPS装置。他们很老,最近有一个星期计数转换问题,因此他们向NTP报告错误的日期。在等待替换它们的过程中,我已完成了一项临时软件修复,该修复程序可以正常运行99%。

我正在从gps提取串行输入,对其进行解析,添加一个校正值,然后将其发送回伪终端。

NTP无法读取端口。如果我使用我的测试读取程序,只要我不尝试以奇偶校验打开端口,它将能够正确读取数据。当然,这就是gps设备的样子。

这是编写例程的程序:

int GPSPortSetup(char *PortName, int *OutputPort)
{
  int gps_fd;
  struct termios line_ctl;
  int OpenFlags;
  int i;
  int master, slave;
  char name[100];

  gps_fd = open (PortName, O_RDWR);

  if (gps_fd == -1)
  {
    perror("Open Failed");
    return -1;
  }
  memset(&line_ctl, 0, sizeof(line_ctl));
  if (tcgetattr (gps_fd, &line_ctl) != 0)
  {
     perror("tcgetattr failed!");
     close(gps_fd);
     exit(-1);
  }

  cfmakeraw(&line_ctl);

  line_ctl.c_iflag = 0;
  line_ctl.c_oflag = 0;
  line_ctl.c_cflag &= ~(CSIZE | CSTOPB);
  line_ctl.c_cflag |= (CS8 | CREAD | PARENB | PARODD);
  line_ctl.c_lflag &= ~(ICANON | ISIG | IEXTEN);

  cfsetspeed(&line_ctl, B9600);

  line_ctl.c_cc[VMIN] = 21;
  line_ctl.c_cc[VTIME] = 5;

  if(tcsetattr(gps_fd, TCSANOW, &line_ctl) !=0)
  {
    perror("tcsetattr failed");
    close(gps_fd);
    exit(-1);
  }

  if(openpty(&master, &slave, &name, &line_ctl, NULL) != 0)
  {
    perror("openpty");
    printf("errno = %i\n", errno);
    exit(-1);
  }

  if(grantpt(master) < 0)
  {
    perror("grantpt");
    exit(-1);
  }
  if(unlockpt(master) < 0)
  {
    perror("unlockpt");
    exit(-1);
  }

  *OutputPort = master;
  printf("%s\n", name);
  return(gps_fd);
}

这是读取例程端口集:

int GPSPortSetup(char Direction, char *PortName)
{
  int gps_fd;
  struct termios line_ctl;
  int OpenFlags;
  int i;

  switch (Direction)
  {
    case GPSREAD:
      OpenFlags = O_RDONLY;
    break;

    case GPSWRITE:
      OpenFlags = O_WRONLY;
    break;

    case GPSRW:
      OpenFlags = O_RDWR;
    break;
  }

printf("%s\n", PortName);
  gps_fd = open (PortName, O_RDWR|O_NOCTTY);

  if (gps_fd == -1)
  {
    perror("Open Failed");
    printf("errno = %i\n", errno);
    printf("EEXIST %i\n", EEXIST);
    printf("EISDIR %i\n", EISDIR);
    printf("EACCES %i\n", EACCES);
    printf("ENAMETOOLONG %i\n", ENAMETOOLONG);
    printf("ENOENT %i\n", ENOENT);
    printf("ENOTDIR %i\n", ENOTDIR);
    printf("ENXIO %i\n", ENXIO);
    printf("ENODEV %i\n", ENODEV);
    printf("EROFS %i\n", EROFS);
    printf("ETXTBSY %i\n", ETXTBSY);
    printf("EFAULT %i\n", EFAULT);
    printf("ELOOP %i\n", ELOOP);
    printf("ENOSPC %i\n", ENOSPC);
    printf("ENOMEM %i\n", ENOMEM);
    printf("EMFILE %i\n", EMFILE);
    printf("ENFILE %i\n", ENFILE);
    exit(-1);
  }
  memset(&line_ctl, 0, sizeof(line_ctl));
  if (tcgetattr (gps_fd, &line_ctl) != 0)
  {
     perror("tcgetattr failed!");
     close(gps_fd);
     exit(-1);
  }

  cfmakeraw(&line_ctl);

  line_ctl.c_iflag = 0;
  line_ctl.c_oflag = 0;
  line_ctl.c_cflag &= ~(CSIZE | CSTOPB);
  line_ctl.c_cflag |= CS8;
  line_ctl.c_cflag |= CREAD;
  line_ctl.c_cflag |= PARENB;
  line_ctl.c_cflag |= PARODD;
  line_ctl.c_lflag &= ~(ICANON | ISIG | IEXTEN);

  cfsetspeed(&line_ctl, B9600);

  line_ctl.c_cc[VMIN] = 21;
  line_ctl.c_cc[VTIME] = 5;

  if(tcsetattr(gps_fd, TCSANOW, &line_ctl) !=0)
  {
    perror("tcsetattr failed");
    close(gps_fd);
    exit(-1);
  }

  return(gps_fd);

}

如果我在读取例程中注释掉设置PARENB的行,则会看到数据。如果我不这样做,则tcsetattr的错误将显示“ tcsetattr失败:参数无效”。

如果我使用实际的串行端口,则该代码有效。我已经测试过了,但是读了gps,打开了一个真实的串行端口,然后通过空调制解调器电缆将其连接到另一个真实的端口。在这种情况下,NTP将上线并正确读取数据。

我去了NTP文档寻求修复。它们显示了一个,但是当我尝试实施该修补程序时,我也会遇到错误。我们使用的单位是Trimble Acutime 2000,Acutime Gold和Palisade。这些站点还没有网络访问权限,因此我不能只读取实时服务器。

我正在运行CentOS 6.5

Acutime 2000进入端口/ dev / ttyrp22。其stty -a为:

speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 21; time = 5;
parenb parodd cs8 hupcl -cstopb cread clocal -crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

它打开/ dev / pts /?当前打开的端口的stty -a是:

speed 9600 baud; rows 0; columns 0; line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>;
eol = <undef>; eol2 = <undef>; swtch = <undef>; start = <undef>; stop = <undef>;
susp = <undef>; rprnt = <undef>; werase = <undef>; lnext = <undef>;
flush = <undef>; min = 1; time = 0;
-parenb parodd cs8 -hupcl -cstopb cread clocal -crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt
-echoctl -echoke

0 个答案:

没有答案