为什么串行通信需要tcsendbreak()才能开始工作?

时间:2016-10-10 18:29:25

标签: c++ linux-kernel serial-port linux-device-driver

我们正在从较旧的操作系统(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时通信有效。

0 个答案:

没有答案