我们正在从较旧的操作系统(OpenSuse 10.2)
迁移到Ubuntu 16.04
,我们的一个应用程序通过串行端口进行通信。通信停止在Ubunutu上工作,但是有一个小的黑客(?)它确实开始工作。该hack是在打开电话后立即发送tcsendbreak(
,如下所示:
fd = open(pname, O_RDWR | O_NOCTTY); //pname becomes /dev/ttyS6
if (fd < 0)
{
printf("Couldnt open comms port \"%s\".\n", pname);
return SYSERR;
}
if (tcsendbreak(fd, 0) < 0)
{
printf("tcsendbreak error\n");
}
执行此操作后,一切正常。我尝试过在不同的点上进行tcflush(没有tcsendbreak),这没有什么区别。
为什么tcsendbreak允许建立通信的原因是什么?关于在不使用tcsendbreak的情况下尝试什么的任何想法?试图理解为什么需要它,如果有一个潜在的问题,这个突破跳过了。
我们按以下方式设置模式:
int r = 0;
struct termios port_opt, *popt;
r |= tcgetattr(fd, &original_port_options);
port_opt = original_port_options;
popt = &port_opt;
cfmakeraw(&port_opt);
/* parity/framing errors come in as nulls. */
popt->c_iflag |= (IGNBRK);
popt->c_cflag |= (CLOCAL);
popt->c_cc[VMIN] = 0; /* ignored by line discipline. */
popt->c_cc[VTIME] = 1; /* ignored by line discipline. */
popt->c_cflag |= CREAD; //enable receiver
r |= cfsetispeed(popt, B19200);
popt->c_cflag &= ~(PARENB);/* turn off parity. */
popt->c_cflag = (popt->c_cflag & ~CSIZE) | CS8; /* 8 bits. */
popt->c_cflag &= ~CSTOPB; /* only 1 stop bit. */
r |= cfsetospeed(popt, B19200);
r |= tcsetattr(fd, TCSANOW, popt);
if (r != 0)
gos_panic("Cant set comms driver parameters");
此外,我们还设置了一个线路规则:
r = ioctl(fd, TIOCGETD, &old_line_discipline);
if (r != 0)
old_line_discipline = -1;
r = map_line_discipline("LINE_DISC", 27);
r = ioctl(fd, TIOCSETD, &r);
请注意,在设置所有这些模式之前发送tcsendbreak时通信有效。