当RTS / CTS流控制开启时,串行写()停止发送

时间:2018-05-03 15:58:26

标签: c linux serial-port flow-control

我正在尝试通过串口(/ dev / ttyS0)从我的Ubuntu机器重复发送数据到RS232-CAN适配器。该消息包含19个字节的数据,每秒发送约4次。在运行的前5-20分钟内,一切都表现正常,但突然发送停止并且write()调用将继续填充输出缓冲区,直到它超过4096字节,此时write()调用开始失败。

仅当通过属性标志CRTSCTS启用硬件流控制时才会出现此问题。起初我认为问题是CTS线路发出停止信号,但在程序运行时检查此标志始终显示为ON。事实上,在发送停止发生的那一点上,没有一个调制解调器控制标志会发生变化。

数据发送停止是突然的,一旦发生,在重新启动程序之前不会再发送任何数据。我尝试在write()之后使用select()(在发送停止后总是超时)和tcdrain()(发送停止后永远阻塞)。数据内容也无关紧要。我已经尝试发送格式正确的CAN消息和随机垃圾,但问题出现了。

另一端的设备配置为使用硬件流量控制,我尝试使用115200和57600的波特率。我不知道还有什么可以检查可能导致问题。在启用RTS / CTS时是否还有其他步骤或配置设置?打开RTS / CTS会增加我不考虑的额外检查吗?

代码

int SetAttributes (int fd, int speed, int parity)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);

        if (tcgetattr (fd, &tty) != 0)
        {
            printf ("error %d from tcgetattr", errno);
            return -1;
        }

        cfsetospeed (&tty, speed);
        cfsetispeed (&tty, speed);

        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;

        tty.c_iflag &= ~IGNBRK;
        tty.c_lflag = 0;
        tty.c_oflag = 0;
        tty.c_cc[VMIN]  = 0;
        tty.c_cc[VTIME] = 5;
        tty.c_iflag &= ~(IXON | IXOFF | IXANY);
        tty.c_cflag |= (CLOCAL | CREAD);
        tty.c_cflag &= ~(PARENB | PARODD);
        tty.c_cflag |= parity;
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag |= CRTSCTS;

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
            printf ("error %d from tcsetattr", errno);
            return -1;
        }

        return 0;
}

void SetBlocking (int fd, int block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);

        if (tcgetattr (fd, &tty) != 0)
        {
            printf ("error %d from tggetattr", errno);
            return;
        }

        tty.c_cc[VMIN]  = block ? 1 : 0;
        tty.c_cc[VTIME] = 5;

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
            printf ("error %d from tcsetattr", errno);
        }
}


int main(int argc, char** argv)
{

    char *portname = "/dev/ttyS0";
    int bytesInBuffer = 0;
    int bytesWritten = 0;
    int modemControlBits = 0;

    int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);

    if (fd < 0)
    {
        printf ("error %d opening %s: %s", errno, portname, strerror (errno));
        return -1;
    }

    SetAttributes (fd, B57600, 0);
    SetBlocking (fd, 0);

    if (tcflush(fd, TCIOFLUSH) == -1)
    {
        printf("error %d flushing: %s\n", errno, strerror(errno));
        return -1;
    }

    while (true)
    {
        bytesWritten = write (fd, "NineteenCharacters!", 19);
        printf("TX: NineteenCharacters!\n");

        ioctl(fd, TIOCOUTQ, &bytesInBuffer);
        printf("Bytes Written: %d --- Bytes Left in Buffer: %d\n", bytesWritten, bytesInBuffer);


        ioctl(fd, TIOCMGET, &modemControlBits);
        printf("Serial Control Bits - LE:%02x - DTR:%02x - RTS:%02x - ST:%02x - SR:%02x- CTS:%02x - DCD:%02x - RNG:%02x - DSR:%02x\n",
            (TIOCM_LE & modemControlBits), (TIOCM_DTR & modemControlBits), (TIOCM_RTS & modemControlBits), (TIOCM_ST & modemControlBits),
            (TIOCM_SR & modemControlBits), (TIOCM_CTS & modemControlBits), (TIOCM_CAR & modemControlBits), (TIOCM_RNG & modemControlBits),
            (TIOCM_DSR & modemControlBits));

        usleep (250000);
    }

    return 0;
}

问题开始时的控制台输出

Bytes Written: 19 --- Bytes Left in Buffer: 19
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100
TX: NineteenCharacters!
Bytes Written: 19 --- Bytes Left in Buffer: 19
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100
TX: NineteenCharacters!
Bytes Written: 19 --- Bytes Left in Buffer: 19
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100
TX: NineteenCharacters!
Bytes Written: 19 --- Bytes Left in Buffer: 22
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100
TX: NineteenCharacters!
Bytes Written: 19 --- Bytes Left in Buffer: 41
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100
TX: NineteenCharacters!
Bytes Written: 19 --- Bytes Left in Buffer: 60
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100
TX: NineteenCharacters!
Bytes Written: 19 --- Bytes Left in Buffer: 79
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100
TX: NineteenCharacters!
Bytes Written: 19 --- Bytes Left in Buffer: 98
Serial Control Bits - LE:00 - DTR:02 - RTS:04 - ST:00 - SR:00- CTS:20 - DCD:40 - RNG:00 - DSR:100

0 个答案:

没有答案