Последовательный порт перестает отвечать на запросы в ubuntu 20.04, но работает с 18.04

#c #serial-port #usb #ubuntu-18.04 #ubuntu-20.04

Вопрос:

Я написал программу на C для непрерывного считывания данных с устройства через последовательный порт USB. Программа безупречно работает в Ubuntu 18.04. У меня идентичная система под управлением Ubuntu 20.04, и та же программа работает неправильно. Он будет считывать несколько КБ с последовательного порта, после чего read () больше не обнаружит никаких данных.

Вот код:

 #include <iostream>
#include <string.h>
#include <fcntl.h>
#include <errno.h> 
#include <termios.h> 
#include <unistd.h> 

int receive_data(int fd, unsigned char read_buf[], int num_requested_bytes)
{
    int total_received_bytes = 0;
    int num_received_bytes = 0;

    // Continue reading the serial port until the number of requested bytes have been read
    while (total_received_bytes < num_requested_bytes)
    {
        num_received_bytes = read(fd, read_buf   total_received_bytes, 
                                  num_requested_bytes - total_received_bytes);
        if (num_received_bytes < 0)
        {
            if (errno == EAGAIN)
            {
                num_received_bytes = 0;
            }
            else
            {
                std::cout << "Encountered error during read(): " << errno << std::endl;
                exit(-1);
            }
        }
        total_received_bytes  = num_received_bytes;

        if (total_received_bytes >= num_requested_bytes)
        {
            break;
        }
    }
    return total_received_bytes;
}

int main() 
{
    // Open serial port
    int fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NONBLOCK);
    int flags = fcntl(fd, F_GETFL);
    //fcntl(fd, F_SETFL,  flags | O_ASYNC); // <------------------- SEE NOTE

    // Read in existing settings, and handle any error
    struct termios tty;
    if(tcgetattr(fd, amp;tty) != 0) 
    {
        close(fd);
        printf("Error %i from tcgetattr: %sn", errno, strerror(errno));
        exit(-1);
    }

    // Set flags
    tty.c_cflag |= (CLOCAL | CREAD);
    tty.c_cc[VTIME] = 0;
    tty.c_cc[VMIN] = 0;
    
    // Raw input mode
    cfmakeraw(amp;tty);

    // Save tty settings, also checking for error
    if (tcsetattr(fd, TCSANOW, amp;tty) != 0) 
    {
        close(fd);
        printf("Error %i from tcsetattr: %sn", errno, strerror(errno));
        exit(1);
    }

    // Attempt to read from port
    int received_bytes;
    unsigned char read_buf[1024];
    while (true)
    {
        received_bytes = receive_data(fd, read_buf, 1024);
        std::cout << "Received " << received_bytes << " bytes. First 2 numbers in frame: " 
                  << ((unsigned int) (read_buf[1] << 8 | read_buf[0])) << ", " 
                  << ((unsigned int) (read_buf[3] << 8 | read_buf[2])) << std::endl;
    }
}
 

Вот пример вывода из программы в Ubuntu 20.04. После 0-3 кадров я больше не получаю никаких данных, и программа бесконечно повторяет мой вызов read ().
В Ubuntu 18.04 программа будет продолжаться бесконечно.

 $ ./main
Received 1024 bytes. First 2 numbers in frame: 65535, 2046
Received 1024 bytes. First 2 numbers in frame: 2046, 3338
Received 1024 bytes. First 2 numbers in frame: 2045, 2046
 

SEE NOTE :
Если я включу флаг O_ASYNC, программа завершит работу на первом read() с I/O Possible печатью в терминале. Если я затем закомментирую строку и перекомпилирую, программа будет работать и непрерывно извлекать кадры, как и ожидалось.

Есть какие-нибудь идеи о том, что может быть причиной этого?

Комментарии:

1. Вы перепрограммируете неблокирующий ввод-вывод, но ваша программа просто тратит циклы процессора на поиск данных. Как вы убедились, что эти две системы «идентичны» ? Вы тестировали прием данных (с вашего таинственного устройства) с помощью стандартной утилиты, например, minicom? Кстати, в receive_data () if () break это избыточный тест с while () циклом.

2. Используя вашу опубликованную программу, я не могу воспроизвести ни одного сбоя, о котором вы сообщили, используя Lubuntu 20.04. Программа загружает процессор и отображает сообщения столько минут, сколько я позволяю программе работать. Проблема не может быть дублирована.

3. Спасибо за ответ! Системы настолько идентичны, насколько могут быть идентичны две альфы Латте Панда. Я изучил связь с minicom и считаю, что есть проблема с прошивкой на устройстве. Я получил новую версию, надеюсь, это исправит проблемы.