Why is tcsendbreak() necessary for serial communication to start working?

元气小坏坏 提交于 2019-12-08 12:50:34

问题


We are migrating from an older OS (OpenSuse 10.2) to Ubuntu 16.04, and one of our applications communicates via a serial port. Communication stopped working on Ubunutu, but with a small hack(?) it does start working. That hack is to send a tcsendbreak() right after the call to open, like so:

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");
}

After doing this everything runs normally. I've tried doing a tcflush at various points (without the tcsendbreak), that didn't make a difference.

What are some reasons why the tcsendbreak would allow communication to be established? Any ideas of what to try without using the tcsendbreak? Trying to understand why its needed, and if there is an underlying issue that this break skips past.

We set the modes the following way:

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");

Additionally, we also set a line discipline:

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);

Note that communication works when sending the tcsendbreak before setting all these modes.

来源:https://stackoverflow.com/questions/39964547/why-is-tcsendbreak-necessary-for-serial-communication-to-start-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!