与pl2303的串行通信不可靠

时间:2019-01-24 13:28:06

标签: c linux serial-port pthreads reliability

已连接两个PL2303设备TX-> RX,RX-> TX并已连接到我的Linux机器

我编写了一个C应用程序,它将执行以下操作:

  1. Port1->“发送已知的256字节数据”-> Port2
  2. Port2读取数据并验证它是否实际接收到Port1发送的相同数据
  3. 端口2->“发送与发送的端口1不同的256个字节的已知数据”->端口1
  4. Port1读取数据并验证它是否实际接收到Port2传输的相同数据

每个端口使用了两个线程

在最后一步中,如果我们在读取之前没有“ sleep + tcflush”,则由Port1读取的缓冲区将在第一步中将部分数据传输到Port2。

这是我的代码段。

// Even port number execution part
        if (!(port_num % 2)) {
            // Write to a given port
            sem_wait(&semaphore[port_num]); // Wait until read is called for odd port
            bytes_written = write(fd, write_buffer_even, size_even);
            if (bytes_written == -1 || bytes_written != size_even) {
                fprintf(fp, "%s: Failed to write buffer\n", port_name);
                thread_params->retval = -errno;
                goto exit;
            }
            // For some reason, I need to add a delay before flushing.
            // The cause of this problem lies in using a USB serial port.
            // If you use a regular serial port, you will not have this problem.
            usleep(300000L); // Required to make flush work
            tcflush(fd, TCIOFLUSH);

            // Read from a given port
            sem_post(&semaphore[port_num + 1]);
            bytes_read = read(fd, read_buffer, size_even);
            if (bytes_read == -1) {
                fprintf(fp, "%s: Failed to read buffer\n", port_name);
                thread_params->retval = -errno;
                goto exit;
            }
            // Check for read bytes, complete & valid or not
            if (size_odd != bytes_read) {
                fprintf(fp, "%s: Read size mismatch - Expected %d bytes,"
                        "Read %zd bytes\n", port_name, size_odd, bytes_read);
                thread_params->retval = -ECOMM;
                thread_params->fail_count++;
            } else {
                if(strncmp(write_buffer_odd, read_buffer, size_odd)) {
                    fprintf(fp, "%s: Read data mismatch - Expected \"%s\""
                            "Read \"%s\"", port_name, write_buffer_odd,
                            read_buffer);
                    thread_params->retval = -ECOMM;
                    thread_params->fail_count++;
                } else {
                    thread_params->success_count++;
                }
            }
        // Odd port number execution part
        } else {
            // For some reason, I need to add a delay before flushing.
            // The cause of this problem lies in using a USB serial port.
            // If you use a regular serial port, you will not have this problem.
            usleep(300000L); // Required to make flush work
            tcflush(fd, TCIOFLUSH);

            // Read from a given port
            sem_post(&semaphore[port_num - 1]);
            bytes_read = read(fd, read_buffer, size_odd);
            if (bytes_read == -1) {
                fprintf(fp, "%s: Failed to read buffer\n", port_name);
                thread_params->retval = -errno;
                goto exit;
            }
            // Check for read bytes, complete & valid or not
            if (size_even != bytes_read) {
                fprintf(fp, "%s: Read size mismatch - Expected %d bytes,"
                        "Read %zd bytes\n", port_name, size_even, bytes_read);
                thread_params->retval = -ECOMM;
                thread_params->fail_count++;
            } else {
                if(strncmp(write_buffer_even, read_buffer, size_even)) {
                    fprintf(fp, "%s: Read data mismatch - Expected \"%s\""
                            "Read \"%s\"", port_name, write_buffer_even,
                            read_buffer);
                    thread_params->retval = -ECOMM;
                    thread_params->fail_count++;
                } else {
                    thread_params->success_count++;
                }
            }

            // Write to a given port
            sem_wait(&semaphore[port_num]); // Wait until read is called for read port
            bytes_written = write(fd, write_buffer_odd, size_odd);
            if (bytes_written == -1 || bytes_written != size_odd) {
                fprintf(fp, "%s: Failed to write buffer\n", port_name);
                thread_params->retval = -errno;
                goto exit;
            }
        }

我将其他USB更改为cp2104,cp2108等串行设备,并且行为仍然相同。我犯的错误是什么,我不想在应用程序中入睡,因为这会影响我的性能。

添加了termios设置:

// Open the port
    sprintf(port_name, "/dev/ttyUSB%d", port_num);
    fd = open(port_name, O_RDWR);
    if (fd == -1) {
        fprintf(fp, "%s: Failed to open %s  port with status:%d\n",
                __func__, port_name, -errno);
        thread_params->retval = -errno;
        goto exit;
    }

    // Set configuration for serial port
    tcgetattr(fd, &config);
    config.c_lflag &= ~(ECHO | ECHONL | ECHOE | ECHOK | ECHONL
            | ECHOCTL | ECHOPRT | ECHOKE);
    cfsetispeed(&config, B9600);
    cfsetospeed(&config, B9600);
    tcsetattr(fd, TCSANOW, &config);

0 个答案:

没有答案